[英]Entity Framework 6 transaction rollback
使用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();
}
}
}
當事情橫盤整理時,是否真的需要回滾? 我很好奇,因為“提交”說明中說:“提交基礎商店交易。”
而“回滾”說明說:“回滾基礎商店交易。”
這讓我感到好奇,因為在我看來,如果未調用Commit,先前執行的命令將不會被存儲(對我來說這是合乎邏輯的)。 但是如果是這種情況,調用Rollback函數的原因是什么? 在EF5中,我使用了TransactionScope,它沒有回滾功能(只有完整功能),這對我來說似乎很合理。 由於MS DTC的原因,我不能再使用TransactionScope,但是也不能像上面的示例那樣使用try catch(即,我只需要Commit)。
您不需要手動調用Rollback
,因為您正在使用using
語句。
DbContextTransaction.Dispose
方法將在using
塊的末尾調用。 如果未成功提交事務(未調用或遇到異常),它將自動回滾事務。 以下是SqlInternalTransaction.Dispose
方法的源代碼(使用SqlServer提供程序時, DbContextTransaction.Dispose
將最終委托給它):
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塊自動回滾任何異常將始終有效。
但是,從實體框架的角度考慮它時,您可以看到為什么所有示例都使用顯式調用來回滾事務。 對於EF,數據庫提供程序是任意的且可插入的,並且可以使用MySQL或具有EF提供程序實現的任何其他數據庫替換該提供程序。 因此,從EF的角度來看,由於EF不知道數據庫提供程序的實現,因此不能保證提供程序將自動回滾已處置的事務。
因此,作為最佳實踐,EF文檔建議您顯式回滾-以防萬一有一天您將提供程序更改為在處置時不會自動回滾的實現。
在我看來,任何優秀且編寫良好的提供程序都將自動在Dispose中回滾事務,因此用try-catch-rollback將所有內容包裝在using塊內的額外努力是過大的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.