使用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 ) 。
你不需要调用 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); } }
只要你永远都是使用SQL Server EF的,不需要显式使用catch来调用Rollback方法。 using块允许自动回滚到任何异常永远是可行的。
但是,如果你仔细想想的话从Entity Framework角度看,你能够理解为什么所有示例使用显式调用Rollback交易 在EF,是虚构的,可插入的数据库提供程序和提供程序都可以替换成MySQL或任何其他具有EF的数据库提供程序的实现。 因此,从EF角度看,不保证提供程序将自动回滚事务,因为disposed EF不知道有关的实现数据库提供程序。
所以,作为最佳实践,EF文档建议你显式Rollback你万一有一天提供程序更改为一个实现,该实现不自动rollback对dispose 。
在我看来,写得精彩和dispose中提供程序将自动回滚事务,因此其他的努力都包装在using块内使用try catch回滚是overkill 。
//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
