0

私は、Hibernate と結合テーブルとの多対多の関係を使用するエンタープライズ アプリケーションに取り組んでいます。本番環境 (大量) で、再現できない非常に散発的なデータベースのデッドロックが発生しています。

カテゴリ.java

public class Category {
    ....
    private Set<Product> products = new HashSet<Product>();
    ...
}

カテゴリ.hbm.xml

<class 
    name="Category"
    table="CATEGORY"
>
    ...
   <!-- uni-directional many-to-many association to Product -->
   <set
       name="products"
       table="CATEGORY_PRODUCT_ASSC"
       lazy="false"
       cascade="none"
    >
        <key column="CATEGORY_ID" />
        <many-to-many class="Product" column="PRODUCT_ID" />
    </set>
</class> 

Product.java、Product.hbm.xml には一連のカテゴリがありません。これは一方向の多対多であるためです。

このテーブルは、とCATEGORY_PRODUCT_ASSCの 2 つの列しかない単純な結合テーブルです。 CATEGORY_IDPRODUCT_ID

Session.saveOrUpdate現在、 CATEGORY_PRODUCT_ASSC 結合テーブルに挿入を取得するという唯一の目的で、Category インスタンス オブジェクトを呼び出しています (Category では何も変更されていません)。

休止状態をオンにするshow_sqlと、次のように表示されます。

update CATEGORY set NAME=?, DESCRIPTION=?, where category_id=?
insert into CATEGORY_PRODUCT_ASSC (CATEGORY_ID, PRODUCT_ID) values (?, ?)

問題は、複数のサーバーで同じカテゴリに対してまったく同じ秒で多くの製品が作成されていることです。

デッドロックが発生すると、update CATEGORY必然的に呼び出しが関係します。これらのupdate CATEGORYSQL ステートメントが実行されないようにする必要があります。

オプション 1: Session.saveOrUpdate(category) を呼び出して Category を更新せず (変更されていないため)、結合テーブル CATEGORY_PRODUCT_ASSC に挿入する方法はありますか?

オプション 2: そうでない場合は、JDBC を介して CATEGORY_PRODUCT_ASSC 行の単純な INSERT を実行することを検討しました。ただし、懸念事項の 1 つは、キャッシュ内の古い Hibernate オブジェクト (Category オブジェクト) です。この可能なアプローチに関するアイデア/推奨事項はありますか?

よろしくお願いいたします。:-)

4

1 に答える 1

0

この問題は解決しました。update categoryそれは声明であることが判明しました。多対多の関係の結合スルーとしてテーブルを使用する代わりに、CATEGORY_PRODUCT_ASSCこの結合テーブルを表すHibernate管理のエンティティを作成しましたCategoryProductAssc...。

このようにして、Categoryオブジェクトで何も変更されていないときに結合テーブルSession.saveOrUpdateの挿入を取得するという唯一の目的で、Categoryインスタンスオブジェクトを呼び出すことなく、関係を直接維持できます。CATEGORY_PRODUCT_ASSC

20の同時実行をスピンアップするCactusテストを作成し、古いコードと新しいコードをテストし、DBAが監視して、古いコードとの同時実行性と新しいコードとの同時実行性がないことを確認しました。

于 2012-09-27T02:39:44.287 に答える