firebird - firebird - 死锁更新与并发更新冲突
问题描述
我正在维护一个旧软件(Firebird 2.5 和 C#.net)。最近我们收到很多“死锁更新与并发更新冲突”的错误。我检查了交易设置。它没有设置等待超时选项:
public override IDbTransaction BeginTransaction(IDbConnection conn)
{
FbTransaction trans = null;
if (conn.State != ConnectionState.Open)
conn.Open();
FbTransactionOptions op = new FbTransactionOptions();
op.TransactionBehavior = FbTransactionBehavior.ReadCommitted | FbTransactionBehavior.RecVersion;
trans = ((FbConnection)conn).BeginTransaction(op);
return trans;
}
那么,为什么我们会超时?它不应该等待一个事务被提交来提交下一个事务吗?
解决方案
当多个事务想要修改同一行时,会发生“死锁更新与并发更新冲突”。只有一个更新程序可以真正更改行并提交。只要第一个事务尚未提交,第二个事务中的更新就会等待(无限期或直到配置的超时)。一旦第一个事务提交,第二个事务中的更新就会以这个错误结束(如果第一个事务已经回滚,第二个事务会继续)。
如果这种情况最近开始发生,您需要确定发生了什么变化。另一个工具是否也开始写入数据库,用户数量是否增加,您是否升级了某些东西(例如 Firebird,或 Firebird ado.net 提供程序版本等),您是否进行了更改,导致长时间运行的事务执行更新?
您的应用程序代码将需要更改以自动重试此错误。还要确保您的事务在时间上不会太“长”(事务越长,发生此类错误的可能性就越大)。此外,您可以尝试将事务行为从 更改FbTransactionBehavior.RecVersion
为FbTransactionBehavior.NoRecVersion
,但这可能会在读取当前由并发事务更新的记录时引入等待,并且如果记录由具有较新交易 ID 的交易。
另请参阅http://www.firebirdfaq.org/faq151/,Firebird中的事务:ACID、隔离级别、死锁和解决更新冲突和事务语句。
推荐阅读
- javascript - javascript toLocaleTimeString 2 位数只有秒或分钟不起作用
- php - 查看 Swagger API 文档
- unity3d - 如何在 Unity 中使用 MapBox 添加自定义兴趣点
- arrays - 从 ModalController 传递数据的问题
- python - numpy / pandas 矢量化“阈值交叉”逻辑
- linux - 如何在bash脚本中解析文件中的行集
- rx-java2 - 列表和项目的依赖于 RxJava 的网络调用
- haskell - 正数递增,负数全部减1
- r - 如何在网格中对齐多个不同大小的图
- c# - CORS、预检选项、IIS 和 WebApi2