Hibernate高并发和用户定义的@Id

时间:2011-10-11 14:19:58

标签: facebook hibernate spring concurrency

首先请原谅我对Hibernate的相对缺乏经验我只是在相当标准的情况下才真正使用它,当然从来没有我必须自己管理主键(@Id)的情况,这是我相信我的地方问题在于。

大纲:我通过FB的批处理API批量加载Facebook个人资料信息,并且需要在本地数据库中镜像这些信息,所有这些都很好,但是当我尝试并行执行时会遇到麻烦。

想象一下,一个消息队列并行处理批量的好友数据,并且有许多相同的共享喜欢和引用(朋友之间),这就是我的问题所在。

我遇到重复的Hibernate ConstraintViolationException,这是由于重复的PK条目 - 因为一个事务在确定一个实体为瞬态后试图刷新它的会话,而事实上另一个事务已经做出了同样的决定并击败了第一个提交,结果如下:

Duplicate entry '121528734903' for key 'PRIMARY' 

引发了ConstraintViolationException。

我已经设法通过从父实体中删除所有级联,并执行原子写入,每个事务一个记录并尝试基本上只捕获任何异常,忽略它们,如果它们确实发生,我设法解决了这个问题。知道另一个交易已经完成了这项工作,但我对这个解决方案并不是很满意,并且无法想象它是最有效的使用hibernate。

我欢迎任何有关如何改进架构的建议......

目前正在使用:Hibernate 3.5.6 / Spring 3.1 / MySQL 5.1.30

附录:目前我正在使用一个hibernate merge(),它最初检查是否存在行,并且要么合并(更新)还是依赖于存在而插入,问题甚至是隔离级别READ_UNCOMMITTED有时候错误的决定,即两个交易决定相同,我再次有一个例外。

锁定对我来说也没有帮助,乐观或悲观,因为条件只是初始插入案例中的一个问题,并且没有要锁定的行,这使得处理并发变得非常困难......

我必须遗漏一些东西,但我已经完成了阅读,我的担心是无法离开hibernate来管理PK我有点被打破 - 因为它在会话的早期检查存在并且有时间同步会话状态无效。

任何对我有任何建议的人......?谢谢。

1 个答案:

答案 0 :(得分:0)

由于我对Hibernate知之甚少,所以需要大量的盐,但听起来你需要做的是指定默认的mysql INSERT语句改为INSERT IGNORE语句。你可能想看看Hibernate中的@SQLInsert,我相信你需要指定应该使用的确切insert语句。对不起,我对语法无能为力,但我认为你可以通过查看@SQLInsert的Hibernate文档以及必要的INSERT IGNORE的MySQL文档来找到你需要的东西。