0

我需要在单个事务中保存到两个不同的 SQL Azure 联合数据库,以便在出现故障时回滚所有更改。现在,我有两个独立的代码块,它们彼此独立地进行交易。我尝试使用 TransactionScope,但显然 SQL Azure 不支持它。

    using (EVENTContext dc = new EVENTContext(
GetConnectionString(1)))
    {
        string federationCmdText = @"USE FEDERATION [fed] ([dist] = '"+ GetDist(1) +"') WITH FILTERING = OFF, RESET";
        ((IObjectContextAdapter)dc).ObjectContext.Connection.Open();
        dc.Database.ExecuteSqlCommand(federationCmdText);
        dc.EVENTS.Add(e);
        dc.SaveChanges();
    }


    using (EVENTContext dc = new EVENTContext(
GetConnectionString(2)))
    {
        string federationCmdText = @"USE FEDERATION [fed] ([dist] = '"+ GetDist(2) +"') WITH FILTERING = OFF, RESET";
        ((IObjectContextAdapter)dc).ObjectContext.Connection.Open();
        dc.Database.ExecuteSqlCommand(federationCmdText);
        dc.EVENTS.Add(e2);
        dc.SaveChanges();
    }

如何在单个事务中保存到多个数据库?我最近开始阅读有关工作单元的内容,但我不确定这是否是我需要的。

4

3 回答 3

0

不幸的是,你不能;不支持。您可以做的最接近的事情是将记录存储在挂起状态(在为此目的添加的列中),如果两者都提交,则将记录状态更改为活动(或类似的东西)。换句话说,您需要自己管理并将这些操作视为长期运行的事务。

于 2012-10-18T01:22:45.270 回答
0

好的,在考虑了一段时间后回答我自己的问题。这是我将尝试做的事情:

1) 为每个用户操作(无论它是什么)生成一个操作 ID,并将其写入根数据库中的表中

2) 将此操作 ID 附加到每一行,以便我可以跟踪为哪个操作添加了哪些行

3)分别提交到每个数据库

4)从根数据库表中删除动作ID

所有这些步骤都将是一个用户操作的一部分,如果在一个步骤中引发异常,则不会执行以下步骤。

在应用程序端,然后我检查从联合表返回的任何内容的操作 ID 是否出现在根数据库表中。如果是这样,则提交更改时出错。如果没有,那就是一次成功的交易。

最后,我可以运行一个辅助角色,它会定期从根数据库表中获取一个操作 ID,并清理具有该操作 ID 的所有行,并在将它们全部删除后,也删除该操作 ID。

于 2012-10-18T02:49:12.603 回答
0

连接到 Azure SQL DB 时,过去不支持 TransactionScope。您要么有单独的上下文独立提交(如在您的代码示例中),要么您必须如上所述实现自己的补偿逻辑。两者都不再需要,因为 Azure DB 现在支持 TransactionScope。请参阅Sql Azure 中的 TransactionScope()

于 2015-11-20T06:20:35.617 回答