在使用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);
}

https://blog.csdn.net/u011127019/article/details/54576873

EF 多线程TransactionScope事务异常事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。相关推荐

  1. 事务_进程 ID 57_与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务

    事务_进程 ID 57_与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品.请重新运行该事务 问题描述 执行下面这个SQL查询语句时,经常会报这个错!事务_进程 ID 57_与另一个进程被死锁在 ...

  2. SQL Server死锁问题:事务(进程 ID x)与另一个进程被死锁在 锁 | 通信缓冲区资源上并且已被选作死锁牺牲品。请重新运行该事务。...

    ### The error occurred while setting parameters ### SQL: update ERP_SCjh_zzc_pl set IF_TONGBU=1 wher ...

  3. SQL Server死锁问题:事务(进程 ID x)与另一个进程被死锁在 锁 | 通信缓冲区资源上并且已被选作死锁牺牲品。请重新运行该事务。

    感觉这篇文章写的不错,读了三遍不是太明白,记录下来: https://www.cnblogs.com/happyhippy/archive/2008/11/14/1333922.html 解决办法: ...

  4. 事务(进程 ID XXX)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品

    多线程高并发量执行方法的过程中控制台出现:事务(进程 ID XXX)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品. 可以尝试对方法加锁来解决问题. //定义lock锁 private fi ...

  5. 读写分离,读写分离死锁解决方案,事务发布死锁解决方案,发布订阅死锁解决方案|事务(进程 ID *)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务...

    前言:         由于网站访问压力的问题,综合分析各种因素后结合实际情况,采用数据库读写分离模式来解决当前问题.实际方案中采用"事务发布"模式实现主数据库和只读数据库的同步, ...

  6. mysql进程通信_事务(进程 ID 70)与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且...

    访问一个内部调研页面,打开第二次就死锁了,搜索了一下,一种可能的情况类似下面这种场景,SQLServer中似乎嵌套的SQL语句会造成死锁,用nolock hint可以解决这个问题. update  t ...

  7. 查询数据的时候 提示事务(进程 ID **)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。

    转自:https://blog.csdn.net/vip__888/article/details/6087850 =======================以下为原文内容============ ...

  8. C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁

    C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 参考文章: (1)C#种死锁:事务(进程 ID 112)与另一个进程被死锁在 锁 (2) 通信缓冲区 资源上,并且已被选作死锁牺牲品.请 ...

  9. 事务(进程 ID 133)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品的解决方案

    事务(进程 ID 133)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品的解决方案 参考文章: (1)事务(进程 ID 133)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品的解决 ...

最新文章

  1. ASP .NET Core Web MVC系列教程:使用ASP .NET Core创建MVC Web应用程序
  2. 语言检测工具-langid
  3. 【Oracle】RAC11gR2Grid启动顺序及启动故障诊断思路
  4. 多线程处理海量数据的解决方案
  5. 微信不再提供小程序打开App?借助H5为App引流的方式你必须知道!
  6. IP路由故障关于BGP的疑问解答
  7. centos 6 php环境,centos6.6 下 安装 php7 + nginx环境的方法
  8. Oracle的分区表
  9. 写作之法 —— 如何切题与点题
  10. dataframe groupby_python pandas获取groupby之后的数据
  11. java编写一个方法printn_Java语言程序设计 基础篇 原书第10版 ,梁勇著 (第六章)编程练习题...
  12. linux终端保存gif,Linux下好用的GIF屏幕截图
  13. 全面接入:ChatGPT杀进15个商业应用,让AI替你打工
  14. 标准型微电脑酸碱度氧化还原电位控制器(UPH -100C)
  15. 奉劝学弟学妹,学完JavaScript就该学TypeScript了,让我们一起了解TypeScript和如何去搭建运行环境吧
  16. 【Web开发】Python实现Web服务器(Ubuntu下Flask使用MySQL数据库)
  17. linux中集计和集约的区别,粗放型经济与集约型经济的区别是什么?
  18. ARM裸机——FS2410 流水灯
  19. 人的一生,你在哪个阶段
  20. 《置身事内》中国政府与经济发展读后梳理

热门文章

  1. STM32学习笔记1.2 STM32的开发方式——写给电信学部学生科技协会的朋友们
  2. 男孩子学计算机什么专业的专科好,男生专科读什么专业比较好
  3. lpoj5576 hongrock的柠檬树
  4. 凌玮科技将在创业板上市:预计募资净额约8亿元,曾踩雷民生理财
  5. 2020-12-06 Delphi XE10.4安装记
  6. 数字化新星何为低代码?何为无代码
  7. PHP 函数filesize获取文件大小错误,一直不变
  8. WARNING *** file size (1080329) not 512 + multiple of sector size (512)
  9. 常见的RuntimeException有哪些
  10. win10下 多媒体设备播放不出声音的解决方案