【问题标题】:Unique constraint violation error in while SaveOrUpdateSaveOrUpdate 时出现唯一约束违规错误
【发布时间】:2012-10-10 10:05:15
【问题描述】:

我有一个名为客户的休眠实体,其中包含有关客户的信息。在我的方法中,我将客户详细信息作为参数获取,我需要将其插入数据库中。因此,要删除重复条目,我会检查该客户是否已存在于数据库中。但问题是,如果在同一时刻使用相同的客户信息对相同的方法进行两次调用,那么我会遇到约束违规错误。我认为 saveOrupdate() 会解决问题,但它没有。有人可以为这种情况提出解决方案吗?

【问题讨论】:

    标签: java multithreading hibernate unique-constraint


    【解决方案1】:

    saveOrUpdate 作用于对象中的主键属性值 例如如果0 是新对象的默认值,并且您的新customer 对象的主键属性设置为0,那么它将始终尝试保存(插入)并且永远不会尝试更新。只有当主键属性为非零值时,它才会尝试更新。这就是saveOrUpdate 无法解决您的问题的原因。

    我不确定你能做些什么比处理 unique 约束异常更好。

    【讨论】:

    • 可以使这个数据库操作发生的同步方法解决问题吗??就像它一次只允许一个线程!
    • 由于在您的方法本身中,您正在检查重复项YES,因为您的重复检查逻辑将优雅地过滤掉第二个客户对象。通常我们没有这样的检查,在这种情况下,第二次调用仍然会失败。
    【解决方案2】:

    saveOrUpdate 的目的完全不同。它用于持久化一个可能已经持久化的实体(具有一个 id 和所有),或者它可能是一个新的 id。它与并发访问无关。

    对于您的问题,有两种选择,称为乐观锁定和悲观锁定。

    悲观锁定:您在检查客户是否存在之前创建一个锁,因此只有当前线程可以继续,它会进行检查并采取相应措施。任何其他带有相同数据的线程都必须等到第一个线程的更新或插入完成。锁可以在数据库中实现,使用休眠或简单的同步块,如果你在单台机器上运行。

    乐观锁定:您只需像现在一样继续前进。但是您放置了一个异常处理程序来处理您在问题中描述的碰撞情况。

    悲观锁定使用同步块可能更容易实现,但它会严重影响性能和可伸缩性。

    【讨论】:

    • 好吧,我尝试使方法同步,但仍然没有帮助,错误仍然存​​在。使方法同步使其线程安全吗??
    • 不,当每条可变信息仅在使用同一监视器的同步块中访问时,您将获得线程安全。确定一些重要的代码是否是线程安全的并不容易。
    • 嘿,詹斯,还有一个疑问!有一个场景,有两个函数说 f1 和 f2。 f1 正在调用函数 f2 并且 f2 已同步。因此,根据您的说法,如果我对函数 f1 进行并发调用,就不会担心函数 f2 是否正在同步??
    猜你喜欢
    • 2022-01-23
    • 2018-01-20
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    相关资源
    最近更新 更多