zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    PostgreSQL表空间、数据库、模式、表、用户/角色之间的关系(转)
    PostgreSQL学习手册-模式Schema(转)
    Python中的编码与解码(转)
    HttpRequest中常见的四种Content-Type(转)
    Django中对静态文件的支持(转)
    IPython的基本功能(转)
    GET请求Referer限制绕过总结
    Linux pwn入门教程(6)——格式化字符串漏洞
    CVE-2015-1641 Office类型混淆漏洞及shellcode分析
    我用着差不多的套路收拾差不多的骗子过着差不多的又一天!
  • 原文地址:https://www.cnblogs.com/llcdbk/p/7833512.html
Copyright © 2011-2022 走看看