EntityFrameworkCore 当中使用了 using 创建事务是否需要显式 Rollback

例子

参考官方例子

using var context = new BloggingContext();
using var transaction = context.Database.BeginTransaction();

try
{
    context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
    context.SaveChanges();

    context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
    context.SaveChanges();

    var blogs = context.Blogs
        .OrderBy(b => b.Url)
        .ToList();

    // Commit transaction if all commands succeed, transaction will auto-rollback
    // when disposed if either commands fails
    transaction.Commit();
}
catch (Exception)
{
    // TODO: Handle failure
}

解析源码

直接定位 transaction 时会定位到EFCore中,这个里面我并没有找到对应的显式Rollback操作,但是经过网络上查询,找到了一个源码中实现了自动 Rollback

System.Data.SqlClient 中的 SqlInternalTransaction 中反编译后,会发现下面的代码

    // .method private hidebysig instance void
      // Dispose(
        // bool disposing
      // ) cil managed
    private void Dispose(bool disposing)
    // .maxstack 8
    // 
    // IL_0000: ldarg.1      // disposing
    // IL_0001: brfalse.s    IL_0018
    // IL_0003: ldarg.0      // this
    // IL_0004: ldfld        class System.Data.SqlClient.SqlInternalConnection System.Data.SqlClient.SqlInternalTransaction::_innerConnection
    // IL_0009: brfalse.s    IL_0018
    // IL_000b: ldarg.0      // this
    // IL_000c: ldc.i4.1
    // IL_000d: stfld        bool System.Data.SqlClient.SqlInternalTransaction::_disposing
    // IL_0012: ldarg.0      // this
    // IL_0013: call         instance void System.Data.SqlClient.SqlInternalTransaction::Rollback()
    // IL_0018: ret
    // 
    {
      if (!disposing || this._innerConnection == null)
        return;
      this._disposing = true;
      this.Rollback();
    }

上面代码中,明显的看出当 _innerConnection 不为 null 时,会在释放后调用 Rollback 来进行回滚

参考

posted @ 2022-08-16 14:27  SpiritLing  阅读(43)  评论(0编辑  收藏  举报