Transaction promoted to Distributed Transaction

简介:

在程序中抛出如下异常:

Message: AutoPopulatePlatformCommand error:Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool..Detial:   at System.Transactions.Oletx.OletxTransactionManager.ProxyException(COMException comException)

   at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)

   at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)

   at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)

   at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)

   at System.Transactions.Transaction.Promote()

   at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)

   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)

   at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)

   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)

   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)

   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)

   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)

   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)

   at System.Data.SqlClient.SqlConnection.Open()

。。。。。。

 

运行环境:

.net framework 4.0,

SQL Server 2008 R2,

Windows Server 2008 R2

起初怀疑是使用了nested TransactionScope,导致自动提升为distributed transaction,而系统将MSDTC服务关闭,所以导致异常。将MSDTC服务打开,能正常运行。

 

程序只需要访问一个数据库,却打开了MSDTC,很明显adds unnecessary overhead and decreases performance.那么为什么会提升为Distributed呢?

 

Google到如下信息:

 

这里只用到了一种resource type,也没有多个databasepromoted只有一种情况:nested connections

写如下测试程序:

      using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, tOptions))

      {

        var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["FLMConnectionString1"].ConnectionString);

        connection.Open();

        var connection2 = new SqlConnection(ConfigurationManager.ConnectionStrings["FLMConnectionString1"].ConnectionString);

        connection2.Open();

 

        scope.Complete();

      }

抛出如下异常:

 

      using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, tOptions))

      {

        var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["FLMConnectionString1"].ConnectionString);

        connection.Open();

        connection.Close();

        var connection2 = new SqlConnection(ConfigurationManager.ConnectionStrings["FLMConnectionString1"].ConnectionString);

        connection2.Open();

 

        scope.Complete();

      }

没有异常

原因确定:多个连接同时打开即使是相同的Connection string,也会promoted to distributed tranaction.

 

在做测试时,犯了一个低级错误,起初写的数据库访问代码如下:

    public void Add(string connectionString, string commandText)

    {

      using (var connection = new SqlConnection(connectionString))

      {

        using (var command = new SqlCommand(commandText, connection))

        {

          command.CommandType = CommandType.Text;

 

          connection.Open();

 

          try

          {

            command.ExecuteNonQuery();

          }

          finally

          {

            connection.Close();

          }

        }

      }

    }

为了测试多个数据库连接是否会导致promoted,将connection.Close()语句注释掉,发现多次调用Add,使用nested transactionscope,多表操作,多表查询,添加,均不会导致promoted。为什么呢?其实是因为使用了using关键字,离开usingscope时,SqlConnectionDispose方法被调用,自动释放了连接,至始至终都是有一个数据库连接,所以不会promoted。通过测试,还确定nested TransactionScope的的确确能够工作,而且使用非常简便,能根据需要自动promoted to distributed transaction

 

有文章说SQL Servier 2005多次连接就会自动提升,没有环境,没做测试,而且已经都SQL Server 2008 R2了,以后也不会用2005了吧,如果这要用,可以写一个Connection Manager类来管理数据库连接,保证通过一个transaction里的所有db访问都使用这一个连接,只有transaction结束了才释放。










本文转自 h2appy  51CTO博客,原文链接:http://blog.51cto.com/h2appy/929976,如需转载请自行联系原作者
目录
相关文章
|
数据库管理 Ruby
Transaction recovery: lock conflict caught and ignored
Transaction recovery: lock conflict caught and ignored环境:RAC 4节点、oracle 11.2.0.4、redhat 5.9 64bit 问题描述: 1.
1844 0
|
6月前
|
Go
【已解决】SendTransactionVM Exception while processing transaction: Transaction‘s maxFeePerGas (200000000
【已解决】SendTransactionVM Exception while processing transaction: Transaction‘s maxFeePerGas (200000000
43 0
|
5月前
|
算法 关系型数据库 MySQL
transaction
【7月更文挑战第21天】
61 7
|
SQL 缓存 安全
Transaction 2 |学习笔记
快速学习 Transaction 2
140 0
Transaction 2 |学习笔记
|
消息中间件 缓存 Oracle
Transaction 1 |学习笔记
快速学习 Transaction 1
116 0
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
SAP RETAIL 执行事务代码WRP1,报错-Transaction WRP1 cannot be executed-
|
存储 算法
Consensus On Transaction Commit
使用分布式一致性算法替代2PC/3PC中的TM,能达到容错的分布式事务提交算法。 改算法使用Paxos和2PC高度融合,达到和2PC一样的延时。
Consensus On Transaction Commit
|
测试技术
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction.
同事反馈一个系统在运行一个存储过程时遇到了下面错误:   Msg 1206, Level 18, State 169, Procedure xxxxxx, Line 118The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction. 费了九牛二虎之力才定位到是我们一个作业把对应的会话给Kill掉了(此作业按条件Kill掉那些阻塞其它会话的会话)。
1398 0
|
SQL 数据库 关系型数据库