小编owe*_*kop的帖子

连接池被嵌套的ADO.NET事务损坏(使用MSDTC)

我无处可寻.

我将展示简单的代码片段,它介绍了如何轻松破坏连接池.
连接池损坏意味着每个新连接打开尝试都将失败.

要体验我们需要的问题:

  1. 在分布式交易中
  2. 嵌套的sqlconnection及其在sqlconnection和sqltransaction中的sqltransaction
  3. do rollback(explict或implict - 根本不提交)嵌套的sqltransaction

当连接池损坏时,每个sqlConnection.Open()抛出以下之一:

  • SqlException:不允许启动新请求,因为它应该带有有效的事务描述符.
  • SqlException:分布式事务已完成.在新事务或NULL事务中登记此会话.

在ADO.NET中有一些线程竞争.如果我Thread.Sleep(10)在代码中放置某个地方,它可能会将收到的异常更改为第二个.有时它会随着任何修改而改变.


如何重现

  1. 启用分布式事务处理协调器窗口服务(默认情况下已启用).
  2. 创建空控制台应用程序
  3. 创建2个数据库(可以为空)或1个数据库并取消注释行: Transaction.Current.EnlistDurable[...]
  4. 复制并粘贴以下代码:

var connectionStringA = String.Format(@"Data Source={0};Initial Catalog={1};Integrated Security=True;pooling=true;Max Pool Size=20;Enlist=true",
            @".\YourServer", "DataBaseA");
var connectionStringB = String.Format(@"Data Source={0};Initial Catalog={1};Integrated Security=True;pooling=true;Max Pool Size=20;Enlist=true",
            @".\YourServer", "DataBaseB");

try
{
    using (var transactionScope = new TransactionScope())
    {
        //we need to force promotion to distributed transaction:
        using (var sqlConnection = new SqlConnection(connectionStringA))
        {
            sqlConnection.Open();
        }
        // you can replace last 3 lines with: (the result …
Run Code Online (Sandbox Code Playgroud)

ado.net msdtc transactions transactionscope

19
推荐指数
1
解决办法
2535
查看次数

标签 统计

ado.net ×1

msdtc ×1

transactions ×1

transactionscope ×1