2011-06-29 14 views
1

Grailsでロックを使用しているときに問題が発生しています。Grailsでロックが動作しない

状況は以下の通りです:私はUserクラスを持っている

、その後、belognsTo =ユーザープロパティを持つ別のクラスUserProperty。

ユーザーが同時にこのプロパティを変更するのを避けるために、ユーザーをロックし、その後に新しいプロパティを変更/追加/削除します。

しかし、ロックが機能していないように見えるのは、どちらの場合でもリクエストがトラフになるからです。擬似コードは次のようになります。

User.lock(userId) 
log.info "Starting modifiying properties" 
addRemoveOrChangePropertiesToUser(userId) 
log.info "Finsih modifing properties" 
User.save(flush: true) 

私の予想している動作は、最初の要求が通過してすべてを記録するということです。そしてそれまで(ユーザーがロックされているため)、2番目のリクエストが待機してから、プロパティの変更を行います。

ログファイルに基づいて、私は完全に異なる動作を見ます。両方のリクエストは待ち時間なしで処理されます(almos simultationiusly)。

私は間違って何を考えていますか? db lockingに関連する概念のいくつかを誤解しましたか?どのようにして目的の動作を達成できますか?

おかげで、 ニコラス

+0

あなたはどのDBを使用していますか? –

+0

これは何か違いがありますか? – Nicolas

+0

なぜ 'user'は小文字ですか?静的クラスメソッドではなく、オブジェクトに対して 'lock(int id)'メソッドを呼び出していますか? –

答えて

-2

私はあなたがこれを正しく実装しているかわかりません。ロックされたインスタンスを変更しようとした後、その後のようにそれをロック...

def instance = Thing.get(1) 
instance.lock() 

そして - 私はあなたのインスタンスを取得する必要があると思います。

+0

これは疑似コードです。この回答コードは、Grailsのドキュメンテーションに反例があります。この方法は、 'def instance = Thing。lock(1) ' –

0

ロックの仕組みがわかりません。これは、他の人が同じインスタンスを休止状態のセッションから取得したときにエンティティをロックするということです。

4

私の機能がコントローラにあったのと同様の問題が発生しました。私は他のスレッドが一度.lockステートメントに当たってブロックされるべきだと考えましたが、それは起こっていませんでした。トランザクションですべてをラップすると、私の問題が解決されました。

したがって、このような何か:後知恵で

User.withTransaction { 
    User.lock(userId) 
    log.info "Starting modifiying properties" 
    addRemoveOrChangePropertiesToUser(userId) 
    log.info "Finsih modifing properties" 
    User.save() 
} 

これは私が推測する意味があります。私はトランザクションが明確な境界(作業単位)を提供する必要があると思われます。そうでなければGORM/hibernateはロックを解除できるときをどのように知っていますか?

コントローラメソッドにはオープンセッションがありますが、トランザクションにはラップされません。サービスメソッドはデフォルトでトランザクションにラップされており、私はそこにこの問題がないと考えています。

+0

これはいいですが、トランザクションサービスメソッドに移動するのが最適です。 –

関連する問題