【问题标题】:Ensuring integrity over 2 databases确保 2 个数据库的完整性
【发布时间】:2014-01-13 14:37:03
【问题描述】:

所以,我有两个数据库......用户数据库和另一个也包含用户表的数据库。两者都有一个电子邮件字段。我想同时更新两个电子邮件字段。

(简化的)代码如下所示:

using(var db1 = new Db1Context())
using(var db2 = new Db2Context())
{
    db1.Users.Single(u => u.Email == oldEmail).Email = someEmail;
    db2.Users.Single(u => u.Email == oldEmail).Email = someEmail;
    db1.SaveChanges();
    db2.SaveChanges(); //what if this fails?
}

所以,尝试 1:

using(var db1 = new Db1Context())
using(var db2 = new Db2Context())
using(var txs = new TransactionScope())
{
    db1.Users.Single(u => u.Email == oldEmail).Email = someEmail;
    db2.Users.Single(u => u.Email == oldEmail).Email = someEmail;
    db1.SaveChanges();
    db2.SaveChanges(); //what if this fails?
    txs.Complete();
}

ArgumentException 和以下堆栈跟踪失败:

[ArgumentException: Value does not fall within the expected range.]
   System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(String nodeName, Guid resourceManagerIdentifier, IntPtr managedIdentifier, Boolean& nodeNameMatches, UInt32& whereaboutsSize, CoTaskMemHandle& whereaboutsBuffer, IResourceManagerShim& resourceManagerShim) +0
   System.Transactions.Oletx.DtcTransactionManager.Initialize() +155
   System.Transactions.Oletx.DtcTransactionManager.get_ProxyShimFactory() +76
   System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken) +160
   System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx) +78
...[etc...]

据我们了解,这是因为Azure does not support distributed transactions

所以现在,我们尝试使用 SqlTransactions:

using(var db1 = new Db1Context())
using(var db2 = new Db2Context())
{
    if(db1.Database.Connection.State == ConnectionState.Closed)
    {
        //transaction can only work on open connection
        db1.Database.Connection.Open(); 
    }
    using(var tx = db1.Database.Connection.BeginTransaction())
    {
        //ArgumentException on next line
        db1.Users.Single(u => u.Email == oldEmail).Email = someEmail;
        db2.Users.Single(u => u.Email == oldEmail).Email = someEmail;
        db1.SaveChanges();
        db2.SaveChanges(); //what if this fails?
    }
}

这会失败并出现错误:

ArgumentException: "EntityConnection 只能用封闭的 DbConnection 构造。"

那么我们该怎么做呢?

【问题讨论】:

    标签: c# entity-framework azure transactions transactionscope


    【解决方案1】:

    简单地说,你不能。您需要实现 2PC 来支持这一点。听起来 Azure 有一些非常严重的限制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-10
      • 1970-01-01
      • 2011-01-22
      相关资源
      最近更新 更多