繁体   English   中英

使用连接表在多对多休眠中死锁

[英]Deadlock in Hibernate Many-to-Many with join table

我正在一个企业应用程序上工作,在该应用程序中我们使用了Hibernate并通过一个联接表使用了多对多关系。 我们看到生产中存在非常零星的数据库死锁(大量),我们无法重新创建死锁。

Category.java

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

Category.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表是一个简单的联接表,只有两列: CATEGORY_IDPRODUCT_ID

现在,我们正在对Category实例对象调用Session.saveOrUpdate ,其唯一目的是获取CATEGORY_PRODUCT_ASSC连接表中的插入内容(Category上没有任何更改)

我打开Hibernate show_sql并看到以下内容:

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

问题在于,我们在同一服务器上的同一秒钟创建了许多产品,所有产品都属于同一类别。

当我们看到死锁时,不可避免地会涉及到update CATEGORY调用。 我们需要阻止执行这些update CATEGORY SQL语句。

选项1:有什么方法可以调用Session.saveOrUpdate(category)并使它不更新Category(因为它没有更改),但是仍然可以将其插入联接表CATEGORY_PRODUCT_ASSC中?

选项2:如果没有,我们考虑过仅通过JDBC对CATEGORY_PRODUCT_ASSC行进行直接插入。 但是,一个问题是缓存中的Hibernate对象(Category对象)过时。 关于这种可能的方法有什么想法/建议?

预先非常感谢您的帮助。 :-)

我们解决了这个问题。 事实证明这是update category声明。 我们没有使用CATEGORY_PRODUCT_ASSC表作为多对多关系的联接,而是创建了一个Hibernate管理的实体来表示该联接表... CategoryProductAssc

这样,我们可以直接保持关系,而不必在Category实例对象上调用Session.saveOrUpdate ,其唯一目的是在Category对象上没有任何更改的情况下,将插入插入到CATEGORY_PRODUCT_ASSC连接表中。

我创建了Cactus测试,该测试可以同时执行20次执行,测试旧代码与新代码之间的关系,并监视我们的DBA,并发现与旧代码的并发与新代码的并发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM