处理事务的提交失败(EF6.1起)
作为6.1的一部分,我们引入了一个新的连接弹性功能的EF:能够探测到,当短暂连接故障影响的事务提交确认自动恢复的能力。该方案的全部细节,在博客文章 SQL数据库连接和幂等问题。综上所述,情形是,当异常在事务处理期间引发提交有两个可能的原因:
- 本次事物提交失败
- 事务提交成功,但连接问题阻止了成功通知到达客户端
当第一情况发生时用户可以重试该操作,但应避免当第二情况发生时的重试。我们面临的挑战是,没有检测到是什么原因阻止了正常的提交数据,应用程序不能选择正确的行动路线。新功能使EF两次(double-check)检查数据库,如果提交成功,就采取正确的行为,并且这个过程是透明的。
使用该功能
为了启用该功能,你需要在你的构造函数DbConfiguration中包含对 SetTransactionHandler的引用。如果你不熟悉 DbConfiguration,应该查看 基于代码的配置。这个特点可以与EF6引入的新功能自动重试组合使用,这将在由于故障无法正确提交事务时提供帮助
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy());
}
}
如何跟踪事务
当启用该功能时,EF会自动添加一个新表__Transactions到数据库。EF创建每个事务时插入该表一个新行并且检查该行是否存在,如果存在则证明这个事务已经提交过了。
EF会做从表中尽可能删除不需要的行,该表可以增长,如果应用程序退出过早,因为这个原因,你可能需要在某些情况下,手动清除该表。