Entity Framework 6事务回滚

使用EF6你有新的事务处理可以使用类似于:

using (var context = new PostEntityContainer())
        {
            using (var dbcxtransaction = context.Database.BeginTransaction())
            {
                try
                {
                    PostInformation NewPost = new PostInformation()
                    {
                        PostId = 101,
                        Content = "This is my first Post related to Entity Model",
                        Title = "Transaction in EF 6 beta"
                    };
                    context.Post_Details.Add(NewPost);
                    context.SaveChanges();
                    PostAdditionalInformation PostInformation = new PostAdditionalInformation()
                    {
                        PostId = (101),
                        PostName = "Working With Transaction in Entity Model 6 Beta Version"
                    };
                    context.PostAddtional_Details.Add(PostInformation);
                    context.SaveChanges();
                    dbcxtransaction.Commit();
                }
                catch
                {
                    dbcxtransaction.Rollback();
                }
            }
        }

实际上是rollback时所需地下行动? 我好奇只因Commit描述说, " 提交基础存储交易"

而Rollback描述说: " 回滚基础存储区交易"

这让我好奇,因为在我看来,如果不调用Commit,以前执行的命令不会存储( 对我这没什么奇怪) 。 但是如果是这样,原因是调用Rollback函数怎么做? EF5中我用TransactionScope哪些没有Rollback函数( 只有Complete ),它看起来很合理。 因为MS DTC原因我无法使用TransactionScope了,可我也不能使用try catch,如上面的例子( 我如果不包含了,我只用Commit ) 。

时间:17年06月07日原作者:Areius 共9个回答
 

 

0
 
 

你不需要调用 Rollback手动,因为你使用的是 using语句。

DbContextTransaction.Dispose将被调用的方法的末尾。 using块中。 然后它会自动回滚事务,只要事务未成功执行( 而不是调用,或者遇到了异常) 。 下面是页面的源代码, SqlInternalTransaction.Dispose方法( DbContextTransaction.Dispose将最终委托给它使用SQLServer提供者时) :

private void Dispose(bool disposing)
{
    // ...
    if (disposing && this._innerConnection != null)
    {
        this._disposing = true;
        this.Rollback();
    }
}

你看字母,则程序检查 _innerConnection( 如果不为null,如果不是,回滚该事务提交, _innerConnection将为null ) 。 让我们看看 Commit是什么:

internal void Commit() 
{
    // Ignore many details here...
    this._innerConnection.ExecuteTransaction(...);
    if (!this.IsZombied && !this._innerConnection.IsYukonOrNewer)
    {
        // Zombie() method will set _innerConnection to null
        this.Zombie();
    }
    else
    {
        this.ZombieParent();
    }
    // Ignore many details here...
}
internal void Zombie()
{
    this.ZombieParent();
    SqlInternalConnection innerConnection = this._innerConnection;
    // Set the _innerConnection to null
    this._innerConnection = null;
    if (innerConnection != null)
    {
        innerConnection.DisconnectTransaction(this);
    }
}
原作者:Mouhong Lin
 
0
 
 

只要你永远都是使用SQL Server EF的,不需要显式使用catch来调用Rollback方法。 using块允许自动回滚到任何异常永远是可行的。

但是,如果你仔细想想的话从Entity Framework角度看,你能够理解为什么所有示例使用显式调用Rollback交易 在EF,是虚构的,可插入的数据库提供程序和提供程序都可以替换成MySQL或任何其他具有EF的数据库提供程序的实现。 因此,从EF角度看,不保证提供程序将自动回滚事务,因为disposed EF不知道有关的实现数据库提供程序。

所以,作为最佳实践,EF文档建议你显式Rollback你万一有一天提供程序更改为一个实现,该实现不自动rollback对dispose 。

在我看来,写得精彩和dispose中提供程序将自动回滚事务,因此其他的努力都包装在using块内使用try catch回滚是overkill 。

原作者:rwb
 
0
 
 
  1. 既然你写了'使用'块实例化事务,则不必提到Rollback函数明确后它会自动回滚( 除非它已提交) 时的处置。
  2. 但是如果你实例化时可以不使用using块,在这种情况下,有必要回滚事务在异常情况下( 正是在catch块中),并且也与Null检查对于更加可靠的代码。 BeginTransaction的工作与事务范围( 不同,后者只需要一个完整的函数如果所有操作被成功完成) 。 而是像是到工作Sql的事务处理。
原作者:Paali
 
0
 
 
     //For Insert/Update/Delete
    public void ExecuteNonQuery(DbCommand comm)
    {
        if (comm == null || string.IsNullOrEmpty(comm.CommandText))
        {
            return;
        }
        else
        {
            if (_database == null)
            {
                _database = DatabaseFactory.CreateDatabase();
            }
            //create a db connection
            using (DbConnection conn = _database.CreateConnection())
            {
                //open connection and begin transaction
                conn.Open();
                comm.Connection = conn;
                //DbTransaction trans = conn.BeginTransaction();
                DbTransaction trans = comm.Connection.BeginTransaction();
                //perform query operation
                try
                {
                    comm.ExecuteNonQuery();
                    //_database.ExecuteNonQuery(comm);
                    //commit changes
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    //rollback changes if error occurs
                    //LogHelper.WriteEntryToEventLog(ex, comm);
                    trans.Rollback();
                    throw ex;
                }
                finally
                {
                    //close and dispose connnection and transaction objects
                    trans.Dispose();
                    conn.Close();
                    conn.Dispose();
                }
            }
            return;
        }
    }

总之,就像可成时发生错误回滚sql命令。 它不会执行该命令,使该行throw ex,不会进行调用,而是将仅重置。

 

 

 

原文:https://ask.helplib.com/c-Sharp/post_1073745

posted @ 2017-11-14 17:05  洛晨随风  阅读(2631)  评论(0编辑  收藏  举报