EFCore 5 中的 Savepoints

Intro

EFCore 5中引入了一个新特性,叫做 Savepoints,主要是事务中使用,个人感觉有点类似于 Windows 上的系统还原点,如果事务发生了异常,可以回滚到某一个还原点。

Savepoints

当我们在一个事务里执行 SaveChanges 的时候,EF Core 会在保存数据之前自动的创建一个 savepointSavepoints 有点类似于系统还原点的概念,我们可以回滚到指定的 savepoint,

当事务发生错误的时候,会自动回滚到事务创建的 savepoint 回滚到事务开始之前的状态,以便于我们做重试或可能的修复错误或其他逻辑

来看一个微软的示例吧:

using var context = new BloggingContext();
using var transaction = context.Database.BeginTransaction(); try
{
context.Blogs.Add(new Blog { Url = "https://devblogs.microsoft.com/dotnet/" });
context.SaveChanges(); transaction.CreateSavepoint("BeforeMoreBlogs"); context.Blogs.Add(new Blog { Url = "https://devblogs.microsoft.com/visualstudio/" });
context.Blogs.Add(new Blog { Url = "https://devblogs.microsoft.com/aspnet/" });
context.SaveChanges(); transaction.Commit();
}
catch (Exception)
{
// If a failure occurred, we rollback to the savepoint and can continue the transaction
transaction.RollbackToSavepoint("BeforeMoreBlogs"); // TODO: Handle failure, possibly retry inserting blogs
}

Sample

我们自己来动手一试,示例代码如下:

var services = new ServiceCollection();
services.AddDbContext<TestDbContext>(options =>
{
options.UseSqlite("Data Source=Application.db;Cache=Shared")
.LogTo(Console.WriteLine, LogLevel.Warning)
;
});
using var provider = services.BuildServiceProvider();
using var scope = provider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<TestDbContext>();
dbContext.Database.EnsureCreated();
Console.WriteLine($"Posts count:{dbContext.Posts.Count()}");
using var transaction = dbContext.Database.BeginTransaction();
try
{
dbContext.Posts.Add(new Post() { Author = "Tom", Title = "Date changed", PostedAt = DateTime.UtcNow, });
dbContext.Posts.Add(new Post() { Author = "Tom", Title = "Date changed", PostedAt = DateTime.UtcNow, });
dbContext.SaveChanges();
transaction.CreateSavepoint("Stage1");
Console.WriteLine($"Posts count:{dbContext.Posts.Count()}"); dbContext.Posts.Add(new Post() { Author = "Alice", Title = "Test", PostedAt = DateTime.UtcNow, });
dbContext.SaveChanges();
transaction.CreateSavepoint("Stage2");
Console.WriteLine($"Posts count:{dbContext.Posts.Count()}"); throw new InvalidOperationException(); transaction.Commit();
}
catch (Exception)
{
Console.WriteLine("Exception throw");
transaction.RollbackToSavepoint("Stage1");
} Console.WriteLine($"Posts count:{dbContext.Posts.Count()}");

示例代码中创建了两个 savepoint,然后抛出了一个异常,捕获异常后回滚到第一个 savepoint

输出结果如下:

可以看到,只有第一个 savepoint 之前的数据保存了下来,第二个 savepoint 虽然数据成功保存了,但是又被回滚了

More

通过 savepoint 我们就可以使得事务控制更加精细,可以更能够好的控制事务中的数据变更

但是需要注意的是,这个功能不要和 Sql Server 中的 Multiple Active Result Sets 一起使用,一旦发生了错误,事务控制可能会发生不可预期的情况。

Savepoints are incompatible with SQL Server's Multiple Active Result Sets, and are not used. If an error occurs during SaveChanges, the transaction may be left in an unknown state.

References

EFCore 5 新特性 —— Savepoints的更多相关文章

  1. EFCore 5 新特性 `SaveChangesInterceptor`

    EFCore 5 新特性 SaveChangesInterceptor Intro 之前 EF Core 5 还没正式发布的时候有发布过一篇关于 SaveChangesEvents 的文章,有需要看可 ...

  2. efcore 新特性 SaveChanges Events

    efcore 新特性 SaveChanges Events Intro 昨天早上看到之前关注的一个 efcore 的 issue 被 closed ,于是看了一眼, ef core 新合并了一个 PR ...

  3. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  4. ElasticSearch 5学习(10)——结构化查询(包括新特性)

    之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...

  5. [干货来袭]C#6.0新特性

    微软昨天发布了新的VS 2015 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下也是昨天发布的新的C#6.0的部分新特性吧.. ...

  6. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  7. 【译】Meteor 新手教程:在排行榜上添加新特性

    原文:http://danneu.com/posts/6-meteor-tutorial-for-fellow-noobs-adding-features-to-the-leaderboard-dem ...

  8. 跨平台的 .NET 运行环境 Mono 3.2 新特性

    Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...

  9. Atitit opencv版本新特性attilax总结

    Atitit opencv版本新特性attilax总结 1.1. :OpenCV 3.0 发布,史上功能最全,速度最快的版1 1.2. 应用领域2 1.3. OPENCV2.4.3改进 2.4.2就有 ...

随机推荐

  1. 你真的了解Python自动化吗?这篇文章可以让你了解90%

    人们为什么使用Python? 之所以选择Python的主要因素有以下几个方面: 软件质量:在很大程度上,Python更注重可读性.一致性和软件质量,从而与脚本语言世界中的其他工具区别开发.此外,Pyt ...

  2. 多任务-python实现-继承Thread类,单独编写一个类(2.1.2)

    @ 目录 1.thread类 1.thread类 threding代码实现 import threading import time class MyThread(threading.Thread): ...

  3. YZMCMS V5.3后台 SSRF

    当改变命运的时刻降临,犹豫就会败北. 前言 此前在测试过程中遇到过此CMS,久攻不下,于是便尝试代码审计,不得不说这套CMS还是挺安全的,读起来也简单,也适合初学代码审计的同学去阅读,不过漏洞真的不多 ...

  4. windows下python3和python2虚拟环境配置

    Python3 被越来越多的开发者所接受,同时让人尴尬的是很多遗留的老系统依旧运行在 Python2 的环境中,因此有时你不得不同时在两个版本中进行开发,调试. 如何在系统中同时共存 Python2 ...

  5. tep用户手册帮你从unittest过渡到pytest

    unittest和pytest是Python的2个强大的测试框架,经常用来做UI自动化或接口自动化.unittest是PyCharm的默认集成工具,也是我们大多数人入门自动化的首选框架.pytest提 ...

  6. Redis入门指导

    前言 本文提供全网最完整的Redis入门指导教程,下面我们从下载Redis安装包开始,一步一步的学习使用. 下载Redis 官网提供的Redis安装包是服务于Linux的,而我们需要在Window下使 ...

  7. 深入理解MySQL系列之redo log、undo log和binlog

    事务的实现 redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能. InnoDB存储引擎体系结构 redo log Write Ahead Log策略 事务提交时,先写重 ...

  8. Python-对比参考目录查找多个文件夹中不同的文件

    改完文件名称后,Dr.he 发现分别保存5个状态的jpg 文件的文件夹出现缺少文件的情况.为了让他少熬夜查找缺失文件,结合网友分享的脚本,写了查找以下代码,满足他的需求,也以防自己忘记.以下代码能解决 ...

  9. Spring-IOC注解编程

    这里的注解是最初级的一些注解,掌握了之后再学习其它的注解 注解扫描 <?xml version="1.0" encoding="UTF-8"?> & ...

  10. JPA 复杂查询 - Querydsl

     添加依赖 <!--query dsl --> <dependency> <groupId>com.querydsl</groupId> <art ...