我对Hibernate非常不满!捕捉ConstraintViolationException并处理不规则的约束
我有一个数据库表(mysql)拥有父子关系,允许我建立一个类别树。我有多个线程可以尝试获取,如果没有,大致同时创建类别路径(包含几个父子行)。
问题是我只使用TRANSACTION_READ_COMMITTED,所以竞争条件可能发生在线程可以为类别子路径创建父 - 子因为它没有找到它,然后(lo!)的另一个线程同时做到了这一点。为了试图解决这个问题,我在父/子ID上设置了一个唯一的约束,并在完整的类别路径上设置了一个唯一的约束。然后,我希望在我的会话中,我会捕获Hibernate ConstraintViolationException,并且知道另一个线程为我写了新的关系,我查询另一个线程在catch子句中写入的行。并尝试在该线程中继续完成它在会话中需要做的所有事情。
这是我能想到的解决多线程同时获取/创建相同长分类路径(具有多个子父 - 子关系行)的问题的唯一方式,并确保维护了独特的约束。
但是,hibernate会使ConstraintViolationException上的会话无效并最终抛出一个断言异常(“com.stagirite.bean.Category条目中的null id(发生异常后不刷新会话)”),所以我的解决方案是不可行的。
如何在不使用悲观锁的情况下通过我的应用程序解决这个问题:“get/create”模型不创建重复行?
安迪
我没有想到版本控制。感兴趣的行是幂等的,这意味着无论线程添加它,将以相同的方式添加它,即具有相同的类别名称和相同的参考ID到其他类别。因此,谁先添加它并没有关系,只是没有重复,并且调用GetAdd函数的线程获取新/旧行的ID。所以我的问题是版本如何解决竞争条件。线程1通过类别名称获得,并发现它不在那里。在同一个事务中它添加了一个休眠版本。看起来似乎可能会出现与版本竞争的情况 – 2011-04-11 15:43:48