问题描述:

系统中多个功能不定期出现“Unable to get error message (6107) (0).”错误,即分布式事务超时,但报出错误的部分功能根本没有使用分布式事务。

原因分析:

推测是存在分布式事务未提交的情况,回到线程池后被复用造成的,例如:

系统中A功能存在分布式事务未提交的问题,处理A功能的线程执行完成后回到线程池,B功能复用了处理A功能的线程,A功能未提交的分布式事务将B功能的代码也包含进去了,依次类推可能还有C、D等功能,直到A功能开启的分布式事务超时报出6107错误,而报错的B或C、D等功能本身是没有问题的。

Demo验证:

   1:      ThreadPool.SetMinThreads(1, 1);
   2:      ThreadPool.SetMaxThreads(1, 1);
   3:   
   4:      ThreadPool.QueueUserWorkItem((x) =>
   5:      {
   6:          Console.WriteLine("33: " + Thread.CurrentThread.ManagedThreadId);
   7:          TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 10));
   8:          using (OracleConnection conn = new OracleConnection(connstr))
   9:          {
  10:              conn.Open();
  11:              var cmd = conn.CreateCommand();
  12:              cmd.CommandText = @"update workitem set name = 'yyxx' where workitemid = '64365dc4-41d7-4057-af68-012d552660e2'";
  13:              cmd.ExecuteNonQuery();
  14:              conn.Close();
  15:          }
  16:          Thread.Sleep(100);
  17:          Console.WriteLine("33: end");
  18:      });
  19:              
  20:      ThreadPool.QueueUserWorkItem((x) => {
  21:          Console.WriteLine("44: " + Thread.CurrentThread.ManagedThreadId);
  22:          try
  23:          {
  24:              while (true)
  25:              {
  26:                  using (OracleConnection conn = new OracleConnection(connstr))
  27:                  {
  28:                      conn.Open();
  29:                      var cmd = conn.CreateCommand();
  30:                      cmd.CommandText = @"update workitem set name = 'xxyy' where workitemid = '68265741-4433-42e9-b7e7-63ae1ce8bbc8'";
  31:                      cmd.ExecuteNonQuery();
  32:                      conn.Close();
  33:                  }
  34:                  Thread.Sleep(100);
  35:              }
  36:          }
  37:          catch (Exception e)
  38:          {
  39:              Console.WriteLine(e);
  40:          }
  41:          Console.WriteLine("44: end");
  42:      });


解决方法:

使用HttpModule 分别在beginRequest和endRequest中判断是否已包含了事务上下文

如果beginRequest中没有事务,endRequest时有未提交事务,则说明当前请求对应的是问题源头;

如果beginRequest和endRequest都有,说明当前请求是线程复用后的受害者。

示例如下:

   1:          protected void context_EndRequest(object sender, EventArgs e)
   2:          {
   3:              Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
   4:              Type t = typeof(Transaction);
   5:              FieldInfo field = t.GetField("complete", BindingFlags.Instance | BindingFlags.NonPublic);
   6:              if (Transaction.Current != null)
   7:              {
   8:                  bool isComplete = (bool) field.GetValue(Transaction.Current);
   9:                  if (!isComplete)
  10:                  {
  11:                      Debug.WriteLine(
  12:                          string.Format(@"Creation Time: {0}\r\nDistributedIdentifier:{1}\r\nLocalIdentifier:{2}",
  13:                              Transaction.Current.TransactionInformation.CreationTime,
  14:                              Transaction.Current.TransactionInformation.DistributedIdentifier,
  15:                              Transaction.Current.TransactionInformation.LocalIdentifier));
  16:                      //Transaction.Current.Rollback();
  17:                      //Transaction.Current.Dispose();
  18:                  }
  19:              }
  20:          }


.NET分布式事务未提交造成6107错误或系统被挂起的问题分析定位的更多相关文章

  1. SQLServer之创建事务未提交读

    未提交读注意事项 使用 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 指定会话的锁定级别. 一次只能设置一个隔离级别选项,而且设置的选项将一直对那个 ...

  2. 记一次mysql事务未提交导致锁未释放的问题

    记一次mysql事务未提交导致锁未释放的问题 ## 查看未提交的事务(3秒内未操作的事务) SELECT p.ID AS conn_id, P.USER AS login_user, P.HOST A ...

  3. MySQL事务未提交导致整个表锁死

    问题及说明: 当一个SQL事务执行完了,但未COMMIT,后面的SQL想要执行就是被锁,超时结束:报错信息如下: mysql> ERROR 1205 (HY000): Lock wait tim ...

  4. SpringMVC+Hibernate架构save方法事务未提交

    今天同事遇到一个问题,一起研究,最后解决,让我对spring的事务管理又加深了印象. 先简单说一下项目:项目是Spring和Hibernate集成的JavaEE项目,MVC架构. 外包在service ...

  5. 分布式事务二阶提交DTS系统

    前端时间写新交易系统时,经常碰到事务一致性问题,网上搜了一下,有一些解决方法,采用了扫表补偿的方式来完成,刚开始只有几个接口需要处理,工作量还可以,但是后续随着需求的增加,这些场景错综复杂,导致大量时 ...

  6. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  7. SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  8. 同一个事务里 查询 已删除可是未提交的数据[bug记录]

    前几天犯了个低级错误.在一个事务方法里老是查询不到某条记录,可是debug卡住时,用db工具查.又能查出值. 经过一番折腾,原来是我在同一个事务里 查询 了已删除可是未提交的数据.当然查询不到了! . ...

  9. 【故障处理】分布式事务ORA-01591错误解决

    [故障处理]分布式事务ORA-01591错误解决 1  BLOG文档结构图       2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你 ...

随机推荐

  1. CentOS 7.0禁用iptables防火墙

    CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. firewall: systemctl start firewalld.service#启动firewal ...

  2. List<T>转换为DataTable

    List<info> infos = Dal.GetInfos(); DataTable dt = new DataTable(); dt.Columns.Add("cName& ...

  3. Inno Setup脚本语法大全

    Inno Setup脚本语法大全 ResourceShare Bruce 11个月前 (10-28) 6136浏览 0评论   Inno Setup 是什么?Inno Setup 是一个免费的 Win ...

  4. echarts在360中以及IE8浏览器不兼容:解决方案

    参考:http://blog.csdn.net/www3300300/article/details/12992489 添加: <head> <meta http-equiv=&qu ...

  5. (实用篇)PHP实现队列及队列原理

    队列是一种线性表,按照先进先出的原则进行的: PHP实现队列:第一个元素作为队头,最后一个元素作为队尾 <?php /** * 队列就是这么简单 * * @link */ $array = ar ...

  6. Spring+SpringMVC+Mybatis+ehcache

    http://www.tuicool.com/articles/myeANv http://www.mamicode.com/info-detail-1151624.html

  7. Qt 串口学习2

    未命名 (2) 1 新建串口 //new serial portmy_serialport= new QSerialPort(); 2给串口设定名字 my_serialport->setPort ...

  8. Chrome A标签的迁移错误:【Error loading page】

    在IE中经常使用A标签用来迁移,正确的写法是 <a href="001.html"></a>即可,不过在chrome上面可能会引发错误无法迁移. 比如用下面 ...

  9. 创建kafkatopic和productor

    cd 到kafka 目录下 创建topic create topicbin/kafka-topics.sh --zookeeper spark1:2181,spark2:2181,spark3:218 ...

  10. svn 安装 、使用(2)

    写在前面的话: p.s.有必要读一读,不然可能会浪费你的时间. 该篇是接着上一篇的,上一篇是看了很多人写的文章,汇总的一些可能的情况,最后还是没有成功.此篇是在一个同学的帮助下成功的,也是在自己做好的 ...