2011-11-12 4 views
0

SQLに特定のコマンドタイムアウト(またはLOCK_TIMEOUT)を指定し、このタイムアウトに達するとnHibernateで例外(またはアラート)を発生させる必要があります。
次は私が書いたものを例擬似コードです:PrimaryKeyID行は他にロックされていた場合はコマンドと悲観的なロックのNhibernate設定クエリのタイムアウト時間

BEGIN TRAN 
SET LOCK_TIMEOUT 500 
SELECT * FROM Foo WITH (UPDLOCK, ROWLOCK) WHERE PrimaryKeyID = 1000001 

:我々は次のSQLを使用して、これを達成するために使用されるSQL Serverで

using (var session = sessionFactory.OpenSession()) { 
    using (var sqlTrans = session.BeginTransaction()) { 
     ICriteria criteria = session.CreateCriteria(typeof(Foo)); 
     criteria.SetTimeout(5); //Here is the specified command timout, eg: property SqlCommand.CommandTimeout 
     Foo fooObject = session.Load<Foo>(primaryKeyIntegerValue, LockMode.Force); 
     session.SaveOrUpdate(fooObject); 
     sqlTrans.Commit(); 
    } 
} 

をSQL Serverによって次のエラーメッセージが表示されています。

Msg 1222, Level 16, State 51, Line 3 
Lock request time out period exceeded 

同様に、ロックタイムアウトまたはコマンドnHibernateを使用して情報をタイムアウトさせます。これを達成するために私を助けてください。
ご協力いただきありがとうございます。

+0

あなたのC#コードは、指定された5秒のタイムアウトを有します。 – mjwills

答えて

3

悲観的なロックを実現するには、ICritieraを使用してオブジェクトの詳細を取得する必要があります。
改変されたコードは以下のとおりである:それはSQLで0.5秒である

using (var session = sessionFactory.OpenSession()) { 
    using (var sqlTrans = session.BeginTransaction()) { 
     ICriteria criteria = session.CreateCriteria<Foo>(); 
     criteria.Add(Restrictions.Eq(fieldOnWhichYouWishToGetTheLock, fieldValue)); 
     criteria.SetLockMode(LockMode.Upgrade); 
     criteria.SetTimeout(5); 
     Foo fooObject = (Foo)criteria.List<Foo>(); 
     //Make the changes to foo object and save as usual. 
    } 
} 
+0

こんにちは@NRao、ソリューションは私のために働いています。複数のフィールドでロックを解除する方法も教えてください。 – Nagesh

+0

元のコードのLockMode.Forceはすでに悲観的なロックを行っていませんか? – mjwills

0

this approachをあなたの目的に適応させることができるのだろうか?もちろん自動ではありません。 resourceNameで渡されたものがエンティティタイプとそのPKの連結である必要がある可能性が高いことを意味します。

また、command_timeoutは有望ですが、私はシステムワイド以外の方法で(アップデートのために)それを行う方法を見ることができません。

関連する問題