弹性链接

    比如说,SQL Server 提供程序包含一个特定的针对 SQL Server(包括 SQL Azure)的执行策略。它很清楚可以被重试的异常类型、具有合理的默认最大尝试次数、合理的两次重试之间的默认延迟等等。

    在为上下文实例配置相关选项的时候就可以指定一个执行策略。这通常是在你派生上下文的 方法中完成,对于 ASP.NET Core 应用程序则在 Startup.cs 中完成。

    这里提供了自定义执行策略的注册机制,如果你想要更改默认的策略,就可以使用它。

    发生错误时自动重试的策略要能够在失败的重试业务块中回放每一个操作。当启用重试时,通过 EF Core 执行的每个操作自身也会成为可重试的操作,也就是说,当发生瞬时错误时每个查询以及每各 SaveChanges() 调用都将被作为一个单元被重试。

    然而,如果你的代码使用 BeginTransaction() 初始化了事务,就意味着你自己定义了要被作为一个单元的一组操作,也就是说发生错误时事务中的一切都需要被回放。如果你在使用了执行策略的情况下这样做,你将收到如下异常信息。

    解决方案会用一个表示所有需要被执行操作的委托来手动调用执行策略。如果发生了瞬时故障,执行策略会再次调用该委托。

    通常在出现连接错误时当前事务就会回滚。然而,事务提交时连接失败是无法知道事务的结果状态的。详细信息请参阅 blog post

    默认情况下,执行策略将会根据事务是否回滚而重新尝试操作。但是,如果新数据库状态不兼容就会导致异常;而如果操作不依赖于某个特定状态就可能导致 数据损坏,比如说使用自动生成主键值的方式插入新的数据行。

    有一些方法可以处理这种情况。

    在事务提交过程中出现连接失败的可能性很低,因此,如果发生该情况,仅仅让应用程序失败是可接受的。

    但是,你需要避免使用存储方生成主键值的方式,如此以确保能够抛出异常,而不是添加重复行。建议使用客户端生成的 GUID 值或者客户端值生成器。

    1. 放弃当前 。
    2. 创建新的 DbContext 并从数据库还原应用程序状态。

    该方法会开启和提交一个事务,其 VerifySucceeded 参数接受一个方法,这个方法会在事务提交发生瞬时错误时被调用。

    如果你需要使用存储方生成主键值,或者需要一个处理不依赖于操作执行的提交失败的常规方式,那么可以在提交失败时为每个被跟踪的事务指定一个ID。

    1. 向数据库添加一个表,用来跟踪事务的状态。
    2. 在每个事务执行前向该表插入一行数据。
    3. 如果在提交过程中连接失败,检查数据库中相应的行是否存在。
    4. 如果提交成功,删除对应的行以避免表数据量无线增长。