3

spring mvc 3.0 と休止状態を使用しています。私はここにいるので、ユーザーがアイテムを追加および削除できる在庫があります。たとえば、合計数量 = 50 です。一度に 2 人のユーザーが、A によって削除された 2 つのアイテムと B によって削除された 4 つのアイテムのように、在庫を更新したいと考えています。つまり、合計数量 = 44 です。 ?? トランザクションが維持されていない場合、50-2=48、50-4=46 のようになります。

4

2 に答える 2

2

バージョン プロパティを使用して、セマンティクスが正しいことを確認します。これは、Hibernate リファレンス ガイドの「楽観的同時実行制御」のセクション全体のトピックです。

于 2012-05-01T05:34:11.530 に答える
-1

バージョン管理で楽観的ロックを使用できます。またはプロパティを永続クラス マッピングに追加するとすぐに、バージョニングによる楽観的ロックが有効になります。XML のプロパティ マッピングは、識別子プロパティ マッピングの直後に配置する必要があります。

<class name="Item" table="ITEM">
    <id .../>
    <version name="version" access="field" column="OBJ_VERSION"/>
     ...
</class>

これにより、item が更新されると、SQL は次のようになります。

update ITEM set INITIAL_PRICE='12.99', OBJ_VERSION=2
where ITEM_ID=123 and OBJ_VERSION=1

別の並行作業単位が同じ行を更新してコミットした場合、OBJ_VERSION 列には値 1 が含まれなくなり、行は更新されません。Hibernate は、JDBC ドライバーから返されたこのステートメントの行数 (この場合は更新された行数であるゼロ) をチェックし、StaleObjectStateException をスローします。

バージョン列またはタイムスタンプ列がない場合でも、Hibernate は自動バージョン管理を実行できますが、同じ永続化コンテキスト (つまり、同じセッション) で取得および変更されたオブジェクトに対してのみです。このバージョニングの代替実装では、オブジェクトが取得された時点 (または永続コンテキストが最後にフラッシュされた時点) の永続プロパティの変更されていない値に対して、現在のデータベースの状態がチェックされます。クラス マッピングで optimistic-lock 属性を設定することにより、この機能を有効にすることができます。

<class name="Item" table="ITEM" optimistic-lock="all">
<id .../>
...
</class>

次の SQL が実行され、Item インスタンスの変更がフラッシュされます: update ITEM set ITEM_PRICE='12.99' where ITEM_ID=123 and ITEM_PRICE='9.99' and ITEM_DESCRIPTION="An Item" and ... and SELLER_ID=45

どちらの場合も、StaleObjectStateException を取得したときに 2 番目のトランザクションを再開するか、更新をマージするかはユーザー次第です。このケースは非常にまれです。それ以外の場合は、リファクタリングしてトランザクション スコープを縮小し、トランザクション スコープを小さくして高速にする必要があります。

詳細については、CHRISTIAN BAUER と GAVIN KING による書籍「Java Persistent with Hibernate」を参照してください。(おすすめされた)

編集:ライアンは正しいです。私は私の答えを修正します。

于 2012-05-01T11:52:44.407 に答える