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

转载于:https://www.cnblogs.com/llcdbk/p/7833512.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值