捕获ConstraintViolationException并处理唯一约束

时间:2011-03-05 16:01:02

标签: mysql hibernate transactions pessimistic-locking

我真的很不高兴Hibernate!

我有一个数据库表(mysql),它拥有允许我构建类别树的父子关系。我有多个线程可以尝试获取,如果没有,则在大致相同的时间创建类别路径(隐含几个父子行)。

问题是我只使用TRANSACTION_READ_COMMITTED,因此竞争条件可能发生在一个线程可以为类别子路径创建父子,因为它没有找到它,然后(lo!)另一个线程做了这个在同一时间。为了尝试解决这个问题,我在父/子id上添加了一个唯一约束,并在完整类别路径上设置了一个唯一约束。然后,我希望在我的会话中,我会捕获hibernate ConstraintViolationException,并且知道另一个线程为我编写了新关系,我查询另一个线程在catch子句中写入的行。并尝试在该线程中继续执行会话所需的所有操作。

这是我能想到的唯一方法来解决多线程同时执行获取/创建相同的长类路径(具有多个子父子关系行)的工作的问题,并确保坚持独特的约束。

但是hibernate使ConstraintViolationException上的会话无效并最终抛出一个断言异常(“com.stagirite.bean.Category条目中的null id(在异常发生后不刷新会话)”)所以我的解决方案是不可行的。 / p>

如何在不使用悲观锁定的情况下在我的应用程序中解决不会创建重复行的“get / create”模型的问题?

安迪

1 个答案:

答案 0 :(得分:0)

由于我不确定你是如何建模你的数据(Self referential table或marterialized path)和相应的hibernate映射,我将尝试回答两个线程试图改变同一事物的部分。您是否尝试过使用hibernate版本控制功能。简而言之,如果一个线程已经更新了类别,那么版本号会增加。可能已启动更新但未完成更新的另一个线程将看到版本更改和回滚。如果你可以发布你的数据模型会有所帮助。

希望有所帮助。