EF 多线程TransactionScope事务异常"事务(进程 ID 58)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。"
解决方案代码一:使用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();
.修改模块名称
_module.UpdateFirstName("模块:" + name);
.修改菜单
this.UpdateFirstName("菜单:" + name);
提交事务
tran.Complete();
}
}
return true;
}
解决方案代码二:使用Monitor封装TransactionScope
using (var tran = new EFTransaction())
{
//修改名称
name = ">>ModuleOperate:" + name;
UpdateFirstName(name);
//2.修改菜单
MenuOperate _menu = new MenuOperate();
_menu.UpdateFirstName(name);
//提交事务
tran.Commit();
}
/// <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);//释放排它锁
}
}
网友评论