恢复 SQL Server 数据库后启用代理

39

我的数据库启用了Service Broker。然后我想从另一个数据库的备份中在程序中恢复我的数据库,但是在恢复后(我在现有的数据库名称上进行恢复),我的方法会出现以下错误:

    Msg 9772, Level 16, State 1, Line 1
The Service Broker in database "ServeDB2" cannot be enabled because there is already an enabled Service Broker with the same ID.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.

这是我的方法:

public void TurnOnBroker()
{
    if (!this.database.BrokerEnabled)
    {
        this.server.KillAllProcesses(this.database.Name);
        this.database.BrokerEnabled = true;
        this.database.Alter();
        RefreshConnection();
    }
}

我应该在这里修复什么?有什么建议吗?

5个回答

70

记下这些选项

ALTER DATABASE mydb SET ENABLE_BROKER

ALTER DATABASE mydb SET DISABLE_BROKER

ALTER DATABASE mydb SET NEW_BROKER

如果你遇到类似已经存在相同ID的启用Service Broker,使用NEW_BROKER。


40
ALTER DATABASE [Database_name] SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 

这将创建新的服务代理


11

每个数据库都有一个由Service Broker使用的唯一ID。此ID必须在Sql Server实例中的所有数据库中是唯一的(理论上应该在全局范围内唯一,但Sql Server没有强制执行的方式)。当您恢复数据库时,可以选择禁用已恢复的数据库中的Service Broker,将其启用并使用备份数据库的GUID(以便它可以接管来自备份数据库的消息处理)或分配新的GUID。您正在尝试使用第二个选项,而您仍然拥有旧数据库,并且会遇到GUID冲突。

详情请参见此处


10
运行此查询以查找使用与您使用的数据库相同服务代理的其他数据库(例如,对于名为DATABASE_NAME的数据库)...
SELECT name, is_broker_enabled, service_broker_guid FROM sys.databases 
WHERE service_broker_guid IN (SELECT service_broker_guid FROM sys.databases where name = 'DATABASE_NAME');

...返回...

name, is_broker_enabled, service_broker_guid
DATABASE_NAME_OTHER, 1, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV
DATABASE_NAME_ANOTHER, 0, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV
DATABASE_NAME, 0, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV

接下来运行以下查询以获取您数据库的新代理...

ALTER DATABASE DATABASE_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE DATABASE_NAME SET NEW_BROKER;
ALTER DATABASE DATABASE_NAME SET MULTI_USER;

再次运行第一个查询,你的数据库应该是列表中唯一的...
SELECT name, is_broker_enabled, service_broker_guid FROM sys.databases 
WHERE service_broker_guid IN (SELECT service_broker_guid FROM sys.databases where name = 'DATABASE_NAME');

...现在返回...

name, is_broker_enabled, service_broker_guid
DATABASE_NAME, 1, ASJCBUHBC-7UIOSUI-IUGGUI87-IUGHUIG

4

我找到了一个非常简单的解决方案 - 只需分配新的服务代理即可,像这样:

public void TurnOnBroker()
    {
        if (!this.database.BrokerEnabled)
        {
            this.server.KillAllProcesses(this.database.Name);

            string brokerCommand = String.Format("ALTER DATABASE {0} SET NEW_BROKER", this.database.Name);
            this.database.ExecuteNonQuery(brokerCommand);

            RefreshConnection();
        }
    }

1
终止进程是有风险的,而且并不一定会立即终止。最好使用WITH ROLLBACK IMMEDIATE - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接