让我们先忘掉Hibernate吧.假设我有两个表,A和B.两个事务正在更新这两个表中的相同记录,但是txn 1更新B然后更新A,而txn 2更新A然后更新B.这是一个典型的死锁示例.避免这种情况的最常见方法是预先定义获取资源的顺序.例如,我们应该更新表A然后B.
回到Hibernate.当我们在一个会话中更新大量实体时,一旦我刷新会话,不同实体的更改将为DB生成相应的插入/更新/删除语句.Hibernate是否有一些算法来决定实体之间的更新顺序?如果没有,Hibernate用于防止第1段中描述的死锁情况的方式是什么?
如果Hibernate维护订单,我怎么知道或控制订单?我不希望我的数据库中的显式更新与Hibernate冲突,并导致死锁.
我有对 API 执行 CRUD 操作的测试。在每次测试之前,都会重新创建 API 中的测试数据。意思是删除数据库中的所有数据并重新插入测试数据。
public void initDatabase() {
answerTranslationRepository.deleteAll();
answerRepository.deleteAll();
userRepository.deleteAll();
//....
Answer answer = new Answer();
AnswerTranslation answerTranslation = new AnswerTranslation("test", answer);
//....
answerTranslationRepository.save(answerTranslation);
answerRepository.save(answer);
}
Run Code Online (Sandbox Code Playgroud)
运行所有测试在大多数情况下都有效,但有时调用answerRepository.deleteAll();会失败,并显示:
2018-04-01 09:09:49.069 ERROR 14260 --- [ main] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [fkco3o4hxryohduthxj2vgnuhxs]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
//.....
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536)
... 54 more
Caused …Run Code Online (Sandbox Code Playgroud)