Adr*_*hum 32 deadlock hibernate database-deadlocks
让我们先忘掉Hibernate吧.假设我有两个表,A和B.两个事务正在更新这两个表中的相同记录,但是txn 1更新B然后更新A,而txn 2更新A然后更新B.这是一个典型的死锁示例.避免这种情况的最常见方法是预先定义获取资源的顺序.例如,我们应该更新表A然后B.
回到Hibernate.当我们在一个会话中更新大量实体时,一旦我刷新会话,不同实体的更改将为DB生成相应的插入/更新/删除语句.Hibernate是否有一些算法来决定实体之间的更新顺序?如果没有,Hibernate用于防止第1段中描述的死锁情况的方式是什么?
如果Hibernate维护订单,我怎么知道或控制订单?我不希望我的数据库中的显式更新与Hibernate冲突,并导致死锁.
Dav*_*rds 40
您描述的问题不是由数据库处理的,根据我的经验,Hibernate也没有完全处理.
你必须采取明确的步骤来避免它成为一个问题.
Hibernate为您完成了一些工作.根据之前的回答,Hibernate确保在隔离的刷新内对插入,删除和更新进行排序,以确保它们以可实现的顺序应用.请参阅AbstractFlushingEventListener类中的performExecutions(EventSource会话):
以特殊顺序执行所有SQL(和二级缓存更新),以便不会违反外键约束:
- 按插入顺序执行插入
- 更新
- 删除集合元素
- 插入集合元素
- 按照执行顺序删除
当具有唯一约束时,了解此顺序非常重要,特别是如果要替换一对多子(删除旧/插入新),但旧子和新子共享相同的唯一约束(例如,相同的电子邮件地址) ).在这种情况下,您可以更新旧条目,而不是删除/插入,或者您可以在删除后刷新,然后继续插入.有关更详细的示例,您可以查看本文.
请注意,它没有指定更新的顺序.检查Hibernate代码会让我认为更新顺序将取决于实体添加到持久化上下文的顺序,而不是它们更新的顺序.这可能在你的代码中是可预测的,但是阅读Hibernate代码并没有让我觉得我会依赖于那个顺序.
我能想到三种解决方案:
| 归档时间: |
|
| 查看次数: |
21557 次 |
| 最近记录: |