我遇到了一个问题。我有一个Hibernate应用程序,它将XML文件中的数据加载到并发模式的表中。某些部分数据可能相同,可能从不同的线程插入。每个线程都在自己的长时间交易中工作。有两个或更多步骤尝试提交事务时存在问题。例如两个线程插入记录到表城市,其中有名称字段的限制。这意味着在flush()或commit()上发生ConstraintViolationException。我想自动处理这些冲突,并希望用旧的已插入对象替换新的问题对象。这可能吗?我在Hibernate中查看saveOrUpdate()和乐观版本控制。Hibernate并发插入
回答
我假设你使用MVCC-based DBMS之一。
如果事务隔离级别不高于READ COMMITTED,可以通过在插入新行之前发出一个查询来检查是否存在具有相同name
的城市的查询来降低冲突概率。
请注意,saveOrUpdate()
不能帮助这里,因为name
不是主键。还要注意,根本不能防止冲突(至少不使用某些DBMS特有的功能),因为基本上它是write skew anomaly的示例,这在基于MVCC的DBMS中无法防止。另外,如果导入XML文件的原子性并不重要,则可以将长事务分解成几个较短的事务,并且在违反约束的情况下简单地重试它们。
谢谢,分解交易是一个好主意。我认为,在并发情况下,城市对象的存在并不能起作用。总会有碰撞的机会。同意saveOrUpdate()已经检查过它。 – 2011-05-17 13:50:39
对不起,您的意思是使用READ UNCOMMITTED并检查存在?我认为它可以帮助。至少未被记录的记录是在交易中共享的,并且在没有记录的会话中进行存在检查并不昂贵。 – 2011-05-17 14:10:37
在这样的情况下,我们使用'insertOrUpdate()'方法的约定和下面的一般流程。该交易是在返回时由'insertOrUpdate()'方法的调用者承诺的:
public MyHibernateObject insertOrUpdate(MyHibernateObject newObj, Session s) {
String name = newObj.getCityName();
MyHibernateObject existingObj = getByCityName(name, s);
if (existingObj == null) {
s.saveOrUpdate(newObj);
return newObj;
} else {
existing.copyImportantFields(newObj);
s.saveOrUpdate(existing);
return existing;
}
}
- 1. Hibernate +并发插入(MySQL INSERT IGNORE)
- 2. hibernate插入?
- 3. Web表单插入并触发插入
- 4. sqlite并发批量插入
- 5. 并发插入流星
- 6. 古典ASP并发插入
- 7. hibernate createSQLQuery批量插入
- 8. Grails/Hibernate批量插入
- 9. Spring中的Hibernate并发性
- 10. hibernate和sqlserver并发问题?
- 11. Mysql的并发插入和锁定
- 12. PostgreSQL的最后插入ID并发
- 13. 暗号链表并发插入
- 14. 并发导致重复记录插入
- 15. 如何处理并发插入JPA
- 16. 触发提醒删除并插入
- 17. sql触发器更新并插入
- 18. 防止SQL Server并发插入锁定
- 19. Oracle之前插入触发器和Hibernate ID生成器设置
- 20. hibernate批量插入仍然会生成很多插入语句
- 21. java hibernate在插入时跳过插入'id'
- 22. 用于Spring/Hibernate开发的Eclipse插件?
- 23. Eclipse插件开发项目中的Hibernate
- 24. Hibernate拦截器帖子插入
- 25. spring + hibernate测试服务/ dao插入
- 26. JPA Hibernate的一对多批量插入
- 27. 使用Hibernate和Spring批量插入
- 28. Hibernate与MySQL插入查询不一致
- 29. 用Hibernate插入浮点值到Mysql
- 30. Hibernate和ORA-01400:不能插入NULL
您好,如果您将问题分享给您的解决方案,我会很高兴。看起来下面是正确的答案,但简单的解释应该更方便。非常感谢。 – Javatar 2012-02-25 18:04:19