【问题标题】:catching ConstraintViolationException and handling unque constraints捕获 ConstraintViolationException 并处理 unque 约束
【发布时间】:2011-07-09 11:06:11
【问题描述】:

我对 Hibernate 真的很不满意!

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

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

这是我能想到的解决多个线程同时进行获取/创建相同的长类别路径(具有多个子父子关系行)的工作的唯一方法,并确保维护唯一约束。

但是休眠使 ConstraintViolationException 上的会话无效并最终引发断言异常(“com.stagirite.bean.Category 条目中的空 id(发生异常后不要刷新会话)”)所以我的解决方案是不可行的。

对于不创建重复行且不使用悲观锁的“获取/创建”模型,我将如何在整个应用程序中解决此问题?

安迪

【问题讨论】:

    标签: mysql hibernate transactions pessimistic-locking


    【解决方案1】:

    由于我不确定您如何对数据(自引用表或材料化路径)和相应的休眠映射进行建模,因此我将尝试回答两个线程试图更改相同内容的部分。您是否尝试过使用休眠版本控制功能。简而言之,如果一个线程已经更新了一个类别,那么版本号就会增加。可能已经开始更新但未完成更新的另一个线程将看到版本更改和回滚。如果您可以发布您的数据模型,将会有所帮助。

    希望对您有所帮助。

    【讨论】:

    • 我没有想到版本控制。感兴趣的行是幂等的,这意味着无论线程添加它,都会以相同的方式添加它,即具有相同的类别名称和相同的引用 id 到其他类别。所以不管是谁先添加,只要没有重复,调用GetAdd函数的线程获取新/旧行的id即可。所以我的问题是版本控制如何解决竞争条件。线程 1 按类别名称获取并发现它不存在。在同一个事务中,它添加了一个休眠版本。看来真的可能有版本的比赛条件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    相关资源
    最近更新 更多