使用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