あなたが選択した分離レベルに応じて、特定のリソースをロックしようとしている - それは、SQLのテーブル全体、行またはブロックにロックすることができます。それは悲観的なロックであり、トランザクションを実行するときにデータベースレベルで保証されます。一方
オプティミスティック・ロックは、複数のトランザクションがめったにないので、ロックが、このアプローチに必要とされない互いに干渉しないと仮定しています。これは、読み取りの間にレコードのバージョンが変更されたかどうかを確認するために、@Version
属性を使用するアプリケーション側のチェックです。
ほとんどの操作が複数のHTTP要求にまたがるので、Webアプリケーションでは楽観的なロック方法を使用することが妥当です。通常、1つの要求でデータベースから情報を取り出し、別の情報で更新します。長いデータベースリソースをロックしてトランザクションを開いたままにすることは、非常に高価で賢明ではありません。そのため、私たちが作業しているデータセットを誰も使用しないことを前提としています。これは安価です。前提が間違っていて、他の人の要求の間にバージョンが変わった場合、Hibernateは行を更新せず、OptimisticLockingException
を投げます。開発者は、この状況を管理する責任があります。
単純な例です。オンラインオークションサービス - あなたはアイテムページを見ています。あなたはその記述と仕様を読む。すべてが、5分と言いましょう。悲観的なロックといくつかの分離レベルを使用すると、この特定のアイテムページ(またはすべてのアイテムも)から他のユーザーをブロックすることができます。楽観的なロックを使用すると、誰もがアクセスできます。あなたがそれに適切なボタンをクリックするようにそれに入札しようとしている項目について読んだ後。その間にこのアイテムを見て、その状態を変更した(所有者が説明を変更した他のユーザーが他の入札者に変更した)場合は、アプリケーションの入札を承認する前に、(アプリの実装に応じて)データベースに保存されているバージョンと同じではありません。
あなたのためにいくつかを明確にする希望。
すぐにお返事ありがとうございます! これは、実際には、トランザクションを開始する前にISOLATION LEVEL(SERIALIZABLE)が実際に悲観的なロックを取得していることを意味しますか? 他の分離レベルについては特にREPEATABLE READについてはどうでしょうか。これも行レベルで悲観的なロックですか? – Dhruv
JPAに関しては、APIをアンラップしてベンダー特有の構成とヒント(apiが時々サポートする)を使用しない限り、分離レベルを直接選択することはできません。ペシミスティックロックを取得すると、繰り返し不可能な読み取りとファントム読み取りを自動的に防止します。 –
しかし、HibernateとSpringでは、トランザクションを開始する前にISOLATION Levelをプロパティとして設定することができます。したがって、これは内部的にトランザクションロックを取る必要があり、これは悲観的なロックでなければなりません。私の更新メソッドで、ISOLATIONレベルがSERIALIZABLEであると言うと、私のトランザクションが実際にロックを持っていれば、その間に他の更新はできないと保証されませんか? – Dhruv