sql >> データベース >  >> RDS >> Oracle

Hibernateでの同時更新処理

    トランザクション管理にSpringを使用する場合、Hibernateによる同時更新の処理方法(Hibernateのメモリ内自動バージョン管理)、またはデータベースにバージョン列を配置して同時更新を手動で処理する必要がある場合、誰かに説明してもらえますか?

    トランザクション管理にSpringを使用しているかどうかは実際には重要ではなく、同時実行管理に関しては関係ありませんが、これは実際にはHibernateによって処理されます。 Hibernateは、2つの戦略を使用して、同時更新を処理できます。楽観的ロックと悲観的ロックです。

    楽観的

    楽観的ロックを使用する場合は、特別な属性(数値、タイムスタンプ)をバージョンとしてマップします。 (つまり、実際にはそのための列があります)。このバージョンは、エンティティを取得して含まれるときに読み取られます。 更新中のwhere句でインクリメント Hibernateによる。

    これがどのように機能するかを説明するために、Personエンティティをid =1で、現在のバージョン=1でロードするとします。保存後、Hibernateは次のような処理を実行します:

    update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
    

    したがって、ここで、2つの同時トランザクションが実行されており、それぞれが同じをロードしていると想像してください。 エンティティ(同じバージョン番号)と名前の変更。

    トランザクション#1が最初にコミットされ、次のクエリが実行されるとしましょう。

    update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;
    

    成功し、バージョンがインクリメントされます。

    次に、トランザクション#2がコミットされ、次のクエリが実行されます。

    update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;
    

    where句はどのレコードとも一致しないため、これは何も更新しません。ここで、楽観的同時実行性の例外が発生します。

    この戦略は、接続を維持しない場合、同時アクセスが頻繁ではない場合に適切であり、拡張性が非常に高くなります。もちろん、バージョン属性をマップする限り、すべてがHibernateによって透過的に処理されます。

    悲観的

    悲観的ロックを使用する場合、Hibernateは、レコードを使い終わるまで(通常はSELECT ... FOR UPDATEを使用して)排他的に使用するためにレコードをロックします。 )。同じレコードにアクセスしようとする他の同時トランザクションは、ロックが解除されるまで中断されます。この戦略は、パフォーマンスを犠牲にして、より優れた予測可能性を提供し、無期限に拡張することはありません。

    参考資料

    • Hibernateコアリファレンスガイド
      • 11.3。楽観的同時実行制御
      • 11.4。悲観的なロック


    1. スプリングブートjpahibernateで>4<24の後にDbへの接続が切断される

    2. MariaDBサーバー10.3での自動データバージョン管理

    3. 2つの日付の間のすべての日付を一覧表示する方法

    4. Microsoft Accessテーブルのヒント–秘訣とガイドラインパート2