2010-11-09 63 views
2

我們已經從sqlite的切換到火鳥嵌入式服務器,因爲FB 似乎支持數據庫的併發更新,但我們有時 有這些例外,從它的到來:用NHibernate設置正確的事務隔離模式,如何?

2010-10-28 15:49:31,242 [56] ERROR NetworkCatcher.Entities.Agent.Server.RunResultManager - Failed to send result to server 32W2K3SP2VM-DEV. NHibernate.Exceptions.GenericADOException: could not update: ExecutionEntry#89_19_32W2K3SP2VM-DEV][SQL: UPDATE Run SET ExecutionId = ?, Source = ?, Destination = ?, ProtocolId = ?, Duration = ?, SampleCount = ?, StartTime = ?, ServerHostName = ?, SamplesSentToServer = ?, SampleInterval = ?, Parameters = ? WHERE Id = ?] ---> FirebirdSql.Data.FirebirdClient.FbException: deadlock 
update conflicts with concurrent update 
concurrent transaction number is 31632 ---> 
FirebirdSql.Data.Common.IscException: deadlock 
update conflicts with concurrent update 
concurrent transaction number is 31632 
    at FirebirdSql.Data.Client.Native.FesDatabase.ParseStatusVector(IntPtr[] 
statusVector) 
    at FirebirdSql.Data.Client.Native.FesStatement.Execute() 
    at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior 
behavior, Boolean returnsSet) 
    at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior 
behavior) 
    at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteNonQuery() 
. 
. 
. 

的FB響應,這是 「你爲什麼認爲這是一個錯誤?這是一個定期更新衝突,導致 由兩個事務同時更新相同的記錄。什麼是 事務隔離模式「

,這句話一直困擾着我兩次 - 一次,因爲我是不愉快 驚訝地發現,我在上面寫上同時相同的記錄 和第二次 - 我不知道是什麼我 事務隔離模式和如何使用它序列寫入 相同的記錄。

對象的映射,被更新爲:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto- 
import="true"> 
    <class name="NetworkCatcher.Entities.Agent.Server.ExecutionManager+ExecutionEntry,NC.Entities.Agent.Server" lazy="false" table="Run" entity-name="ExecutionEntry"> 
    <id name="Id" column="Id" type="string" > 
     <generator class="assigned"/> 
    </id> 
    <property name="ExecutionId"/> 
    <property name="Source"/> 
    <property name="Destination"/> 
    <property name="ProtocolId" type="string"/> 
    <property name="Duration"/> 
    <property name="SampleCount"/> 
    <property name="StartTime"/> 
    <property name="ServerHostName"/> 
    <property name="m_samplesSentToServer" column="SamplesSentToServer" type="int" access="field" /> 
    <property name="SampleInterval"/> 
    <property name="Parameters" type="binary"/> 
    </class> 
</hibernate-mapping> 

我相信有好心人在那裏,誰知道答案 我的問題。請,請,請從你的智慧分享...

感謝。

回答

6

事務隔離模式通常是在你的hibernatem.cfg.xml文件中設置:

<屬性名= 「connection.isolation」 > READCOMMITTED < /屬性>

http://www.nhforge.org/doc/nh/en/index.html#configuration-hibernatejdbc

你可以找到對於System.Data.IsolationLevel MSDN文檔中的每一個有效的值和描述的列表:

http://msdn.microsoft.com/en-us/library/system.data.isolationlevel.aspx

你必須檢查火鳥文檔,看看它支持哪些。

關於你例外,你在更新記錄時,創下了僵局,這是在關係數據庫中的預期。您應該準備好捕獲死鎖異常並重新嘗試操作。這與NHibernate沒有任何關係,並且與關係數據庫如何支持事務有關。基本上,你遇到了一種情況,你試圖在兩個不同的事務中更新相同的兩條記錄A和B.一個事務對A有一個鎖,另一個事務對B有一個鎖。每個事務都需要鎖定另一個記錄才能完成。數據庫引擎選擇一個死鎖受害者,回滾其事務,拋出一個死鎖異常,並允許其他事務完成。如果它沒有這樣做,那麼這兩個事務將永遠等待(或事務超時)以完成另一個事務。 (這可能是記錄,r1..rN,以及多筆交易更復雜的週期,但同樣的想法適用。)最終結果是,作爲一個應用程序開發人員,你必須要準備重新嘗試操作死鎖,無論您是使用NHibernate,原始ADO.NET還是使用關係數據庫的其他技術。

2

除了James所解釋的默認隔離級別之外,您還可以使用ISession.BeginTransaction的過載來設置單個事務的隔離級別,其過程爲IsolationLevel

請注意,這不是純粹的事情:它是一個標準的ADO.NET概念,所以你可以在MSDN中閱讀更多關於它的內容。

相關問題