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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM