问题描述:

系统中多个功能不定期出现“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. cookie 作用域

    在http://xiaoyou-game.com/user/login方法中设置cookie: setcookie('username',$username,time()+3600,'/user/', ...

  2. 【转】为什么我要用 Node.js? 案例逐一介绍

    原文转自:http://blog.jobbole.com/53736/ 介绍 JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样, ...

  3. 如何在UIAlertView中显示进度条

    今天这个问题是,在一个iPhone程序中,我要在后台做大量的数据处理,希望在界面上显示一个进度条(Progress Bar)使得用户了解处理进度.这个进度条应该是在一个模态的窗口中,使界 今天这个问题 ...

  4. java 基本类型

    1 常量 整数 byte 1字节 8位 -27~27-1 0111 1111 ~1000 0000 short 2 16     int 4 32     long 8 64     1111 111 ...

  5. Python4周 入职培训的过程

    这是我在过去几家公司招聘到工程师,Python入职培训的过程.时间分为4周,全部自学,仅提供大纲.适用于Web方向:1.Week1:读完<简明Python教程>,适应Python开发环境2 ...

  6. 博客引索 - imsoft.cnblogs

    Java C Delphi 日常工具 图片处理 视频处理 系统工具 知识经验 奇思妙想 网站推荐

  7. hdu 3666 Making the Grade

    题目大意 给出了一列数,要求通过修改某些值,使得最终这列数变成有序的序列,非增或者非减的,求最小的修改量. 分析 首先我们会发现,最终修改后,或者和前一个数字一样,或者和后一个数字一样,这样才能修改量 ...

  8. 高效而轻松的sed命令

    sed(stream editor)是一款高效的流编辑器,它一次只处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的 ...

  9. SAP 审计

    SAP 权限审计:SA38--- RSUSR002 还有其它事务码待续,,,

  10. 使用oss批量上传图片

    <?php set_time_limit(0);// 引入自动加载类// 确保路径是否正确require_once 'autoload.php';// 确定参数 需要申请$accessKeyId ...