错误 - LINQ /与多个数据库连接的TransactionScope(Error - LINQ

2019-07-30 03:37发布

我有一个宏大的一次包装几个交易到2个不同的数据库相同的SQL Server上。 我最初在和网络DTC访问麻烦,我解决了。 现在,我继续得到错误是“与底层事务管理器通信失败。”

我们在一个数据库中的一些客户档案,当这些配置文件已经过时,我们希望将其移动到存储的“存档”数据库。 此举仅仅是将其添加到归档数据库,并从主/活数据库中删除它们(幽默斜体)。 我对每个数据库一个DataContext。 下面的代码进行添加,然后试图用第二的DataContext时得到的删除错误。 我只一直在与LINQ几个月,我已经冲刷了过去几天的文章。 我想知道如果有什么错我的代码或如果还有什么不与DTC或适当配置???

我们在VMware上运行我的工作站和服务器。 - 工作站是Windows 7的SP1 - 服务器是Windows和SQL Server 2008R2

常规的“移动”:

private int MoveProfileToArchiveDB( int iProfileId )
{
    int rc = RC.UnknownError;

    // get new Archive profile object
    ProfileArchive.ProfileInfo piArchive = new ProfileArchive.ProfileInfo();

    // 'Live' DataContext
    using ( ProfileDataContext dbLive = new ProfileDataContext() )
    {
        // get Live profile
        ProfileInfo piLive = ProfileInfo.GetProfile( dbLive, iProfileId );

        // copy Live data to Archive profile object... including the id
        ProfileArchive.ProfileInfo.CopyFromLive( piLive, piArchive, true );
    }

    bool bArchiveProfileExists = ProfileArchive.ProfileInfo.ProfileExists( piArchive.id );

    // make the move a transaction... 
    using ( TransactionScope ts = new TransactionScope() )
    {
        // Add/Update to Archive db
        using ( ProfileArchiveDataContext dbArchive = new ProfileArchiveDataContext() )
        {
            // if this profile already exists in the Archive db...
            if ( bArchiveProfileExists )
            {
                // update the personal profile in Archive db
                rc = ProfileArchive.ProfileInfo.UpdateProfile( dbArchive, piArchive );
            }
            else
            {
                // add this personal profile to the archive db
                int iArchiveId = 0;
                piArchive.ArchiveDate = DateTime.Now;
                rc = ProfileArchive.ProfileInfo.AddProfile( dbArchive, piArchive, ref iArchiveId );
            }

            // if Add/Update was successful...
            if ( rc == RC.Success )
            {
                // Delete from the Live db
                using ( ProfileDataContext dbLive = new ProfileDataContext() )
                {
                    // delete the personal profile from the Profile DB
                    rc = ProfileInfo.DeleteProfileExecCmd( dbLive, iProfileId );    // *** ERROR HERE ***
                    if ( rc == RC.Success )
                    {
                        // Transaction End (completed)
                        ts.Complete();
                    }
                }
            }
        }

    }

    return rc;
}

笔记:

  1. 我有删除,他们都在外面的TransactionScope工作几种不同的方法。
  2. ProfileInfo是主个人资料表,大致是两个Live和归档数据库相同。

任何帮助是极大的赞赏! 非常感谢...

Answer 1:

而不是继续十字交叉的意见,我决定发布这个作为一个答案,而不是。

  • 不要使用错误代码。 这就是例外了。 码流更难以阅读和错误代码返回邀请被忽略。 例外使代码更易于阅读和很不容易出错。

  • 如果你使用一个TransactionScope,记得要经常设置隔离级别明确。 请参阅使用新的TransactionScope()是有害的 。 SERIALIZABLE的隐含隔离级别几乎从来没有要求,具有极大的负面影响的规模。

  • 交易升级。 当多个连接在一个事务范围内打开,他们可以升级交易为分布式事务。 该行为从版本有所不同的版本,一些人试图将其记录下来,例如。 TransactionScope的:交易行为的升级 :

SQL Server 2008是更聪明那么SQL Server 2005中,并能自动检测是否在某个事务指向同一个物理数据库中的所有数据库连接。 如果是这种情况下,交易仍然是一个本地事务,并没有升级到分布式事务。 不幸的是有几个注意事项:

  • 如果打开的数据库连接是嵌套的,该交易仍是升级到分布式事务。
  • 如果在交易中,连接到另一个持久资源取得,交易立即升级到分布式事务。

由于您的连接(与所使用的两个数据contextes)指向不同的数据库,甚至在SQL Server 2008中您的TransactionScope将升级为分布式事务。

争取你的应用程序到DTC在至少在两个方面危害:

  • 吞吐量将通过地面下沉。 一个数据库可以支持每秒几千本地事务,但每秒分布式事务的只有几十(也许几百个低)。 这主要是因为复杂的两个阶段提交 。
  • DTC需要协调:MSDTC。 [待MSDTC做出安全性增强]进行配置更具挑战性,它肯定是意想不到的开发者和发现MSDTC在自己的应用需要。 链接的文章中描述的步骤可能是你错过了什么现在 。 对于Windows Vista / Windows 7中/ Windows Server 2008中/在Windows Server 2008R2的步骤描述MSDTC在Windows Vista和Windows Server 2008中, 如何在Windows 2008上配置DTC和其他类似物品。

现在,如果你解决以下上面提到的文章,你的代码应该是工作MSDTC通信,但我仍然相信这归档应该在客户端运行的代码EF发生。 有更好的工具, SSIS是一个典型的例子。 运行SSIS每晚安排工作会更有效地转移那些未使用的配置文件。



文章来源: Error - LINQ/TransactionScope with multiple database connections