EF 多线程TransactionScope事务异常"事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"
来源:互联网 发布:淘宝举报中心网站 编辑:程序博客网 时间:2024/05/16 09:20
一、在使用EF的TransactionScope事务时,如果多线程程序,经常会抛出如下异常
{"事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"}
同一个TransactionScope逻辑操作事务在多线程中启动时会抛出异常。
解决方案:
使用线程锁,对同一个事务操作,仅允许一个线程执行
示例说明
1.出现异常的代码
事务操作定义
using (var tran = new TransactionScope()){ ModuleOperate _module = new ModuleOperate(); //1.修改模块名称 _module.UpdateFirstName("模块:" + name); //2.修改菜单 this.UpdateFirstName("菜单:" + name); //提交事务 tran.Complete();}
多线程调用定义
Action<object> update1 = (number) =>{ while (true) { //将上线文实例放在本线程中创建 MenuOperate _menu = new MenuOperate(); _menu.UpdateName(Count.ToString()); Console.WriteLine("-------"); Console.WriteLine(_menu.GetName2()); Count++; Thread.Sleep(1000 * Convert.ToInt32(number)); }};for (int i = 0; i < 3; i++){ Task.Factory.StartNew(update1, i + 1);}
2.解决方案代码一:使用lock锁定
//对于锁推荐使用静态私有静态变量private readonly static object _MyLock = new object();/// <summary>/// 事务, 多表修改/// </summary>/// <param name="name"></param>/// <returns></returns>public bool UpdateName(string name){ lock (_MyLock) { using (var tran = new TransactionScope()) { ModuleOperate _module = new ModuleOperate(); 1.修改模块名称 _module.UpdateFirstName("模块:" + name); 2.修改菜单 this.UpdateFirstName("菜单:" + name); 提交事务 tran.Complete(); } } return true;}3.解决方案代码二:使用Monitor封装TransactionScope
使用代码:
using (var tran = new EFTransaction()){ //修改名称 name = ">>ModuleOperate:" + name; UpdateFirstName(name); //2.修改菜单 MenuOperate _menu = new MenuOperate(); _menu.UpdateFirstName(name); //提交事务 tran.Commit();}
EFTransaction类定义:
/// <summary>/// 自定义事务处理,/// 此版本,数据库上下文会出现多个,所以事务使用 TransactionScope /// 使用排它锁,确保事务的单线程执行/// </summary>public class EFTransaction : IDisposable{ private readonly static object _MyLock = new object(); /// <summary> /// 当前事务对象 /// </summary> private TransactionScope tran = null; public EFTransaction() { Monitor.Enter(_MyLock);//获取排它锁 this.tran = new TransactionScope(); } /// <summary> /// 提交 /// </summary> public void Commit() { tran.Complete(); } /// <summary> /// 混滚操作,在Dispose(),中自动调用回滚 /// </summary> public void Rollback() { //提前执行释放,回滚 if (tran != null) tran.Dispose(); } public void Dispose() { if (tran != null) tran.Dispose(); Monitor.Exit(_MyLock);//释放排它锁 }}
使用验证代码:不同线程对于同一个事务操作多个事务实例,在当前程序中事务操作代码顺序同步执行,不会出现异常和数据异常。
Action<object> update1 = (number) =>{ while (true) { //同一个线程使用多个事务 MenuOperate _menu = new MenuOperate(); ModuleOperate _module = new ModuleOperate(); ////事务操作一 _menu.UpdateName(Count.ToString()); Thread.Sleep(Count); //错开等待时间,测试多线程异步问题 //事务操作二 _module.UpdateName(Count.ToString()); Console.WriteLine("-------"); Console.WriteLine(_menu.GetName2()); Count++; Thread.Sleep(1000 * Convert.ToInt32(number)); }};for (int i = 0; i < 3; i++){ Task.Factory.StartNew(update1, i + 1);}
更多:
EF线程安全问题
EntiryFramework中事务操作(三)事务回滚数据模型和数据库不对应问题
EF中Sum()异常:到值类型“System.Decimal”的强制转换失败,因为具体化值为 null。
0 0
- EF 多线程TransactionScope事务异常"事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"
- 触发器引起"事务(进程 ID 88)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"的错误
- 事务(进程 ID 66)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务
- sqlserver.jdbc.SQLServerException: 事务(进程 ID 246)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务
- 事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务
- 事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务
- 事务(进程 ID %1!)与另一个进程已被死锁在资源 {%2!} 上,且该事务已被选作死锁牺牲品。请重新运行该事务。
- 事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行
- biztalk 2009 原因: 事务(进程 ID 128)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品
- 查询数据的时候 提示事务(进程 ID **)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。
- [易飞]事务与另一个进程被锁在锁资源上,并且被选做锁牺牲品
- 事务(进程 ID )与另一个进程已被死锁在 lock 资源上
- 另一个进程已被死锁在 lock 资源上
- 性能提高及事务进程死锁问题
- 事务与死锁
- 事务死锁
- EF TransactionScope异常:分布式事务已完成。请将此会话登记到新事务或 NULL 事务中。
- 【数据库事务】--事务死锁与检测
- 计算机网络之网络层(IP地址)
- 根据前序遍历和中序遍历结果构造二叉树
- 【ArcGis for javascript从零开始】之一ArcGIS API for Javascript library 3.9安装说明
- Java 文件下载
- 汉诺塔系列1
- EF 多线程TransactionScope事务异常"事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"
- 云服务器 linux文件系统异常an error occurren during the file system check导致服务器启动失败
- jzoj C组 2017.1.16 比赛
- LeetCOde441详细分析并附求解代码
- 前端技术学习之选择器(十三)
- Spring Mvc+Spring+Mybatis的Maven项目搭建
- 【ArcGis for javascript从零开始】之二 ArcGis加载天地图
- jdbcTemplate常用的调用方式整理
- matlab2016b的更新