簡體   English   中英

NHibernate讀取事務

[英]NHibernate Transactions on Reads

我已經閱讀了文檔和解釋為什么強烈建議在NH中使用讀取操作的事務。 但是,我還沒有完全“買進”它。 有人可以試着解釋它而不只是告訴我RTFM,我已經做過了嗎? ;)

其中一位作者的這篇文章可能有你的答案:

即使我們只讀取數據,我們也希望使用事務,因為使用事務確保我們從數據庫中獲得一致的結果。 NHibernate假設對數據庫的所有訪問都是在事務下完成的,並強烈反對在沒有事務的情況下使用會話。

撇開處理交易的安全問題,假設交易成本高昂且我們需要對其進行優化是假的。 如前所述,數據庫始終在事務中運行。 數據庫已經過大量優化,可以處理事務。 問題是這是每個聲明還是每批。 創建和處理事務需要完成一些工作,並且每個語句必須執行它實際上比每批執行它更昂貴。

其他人所說的是真的,但是他們沒有指出不自行控制事務的問題是如果你在沒有顯式事務的情況下執行幾個NHibernate操作,那么每個操作都將在單獨的事務中進行

因此,您可以輕松地獲得操作之間的不一致。 通過顯式啟動NHibernate事務然后執行其中的操作,可以保證這些操作的一致性。

當然,對於任何隱式啟動事務的數據訪問層,如果不這樣做,這是正確的。 它不僅限於NHibernate。

var fooIdFromDb = ExecuteQuery("Select Id from Foo where something = somethingelse");
var barsFromDb = ExecuteQuery("Select * from Bar where FooId = " + fooIdFromDB);

如果某個其他事務在兩個查詢之間從Bar中刪除行,該怎么辦? 您將遇到幻像數據問題。 這不是NHibernate的具體問題。 在不使用事務的情況下,您將遇到與任何其他類型的數據庫訪問相同的問題。 您應該閱讀有關交易的手冊,而不是NHiberante手冊。

讓我們關注如果你使用交易會發生什么。 在處理結束時,但在開始讀取數據(即View)之前關閉Session是習慣的,但不是強制性的。 此方法在術語“ 在視圖中打開會話 ”下傳播(盡管它顯然具有防止在關閉之前讀取的模式)。 此模式通常用於Web應用程序,其中會話在請求到達時打開,並在寫入響應流之前關閉。

(N)Hibernate需要會話和事務。 當您在不使用顯式交易的情況下閱讀時,將為您設置交易。 在提交事務后讀取時,行為取決於NH配置和驅動程序。

ODBC和JDBC都沒有定義連接關閉時發生的情況以及未提交或未返回的數據。 重新打開連接后,可能會自動啟動新事務。

使用非事務性訪問只能與NHibernate配置中顯式設置auto-commit一起使用。 如果沒有,則使用驅動程序的默認值,它可能有效,或者可能無效。

簡而言之,當您不在讀取上使用事務時,存在許多缺點和未定義的行為。 它會經常工作,但這取決於配置,應用的模式,驅動程序。 您很有可能獲得LazyInitializationException ,這是在提交后讀取而不打開新事務的常見結果。

“最佳實踐”是將一個事務用於讀/寫,另一個用於只讀。 這在前面的鏈接“我可以在會話中使用兩個事務”部分進行了簡要描述,但需要更多的實現。

它不僅是“使用事務進行讀取”,它還是:“使用您用於寫入的相同事務進行讀取”。 (然后,雖然這是真的,但實際應用程序將取決於您當前的模式,有多少層,緩存和配置)。

更新:擴展了一下,刪除了一些含糊之處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM