Java 保存或更新时出现唯一约束冲突错误
我有一个名为customer的hibernate实体,它包含关于customer的信息。在我的方法中,我获取客户详细信息作为参数,需要将其插入数据库中。因此,为了删除重复条目,我正在检查数据库中是否已经存在该客户。但问题是,如果使用相同的客户信息在同一时刻对相同的方法进行两次调用,那么我将得到约束冲突错误。我原以为saveOrupdate()可以解决这个问题,但事实并非如此。有人可以为这种情况提出解决方案。Java 保存或更新时出现唯一约束冲突错误,java,multithreading,hibernate,unique-constraint,Java,Multithreading,Hibernate,Unique Constraint,我有一个名为customer的hibernate实体,它包含关于customer的信息。在我的方法中,我获取客户详细信息作为参数,需要将其插入数据库中。因此,为了删除重复条目,我正在检查数据库中是否已经存在该客户。但问题是,如果使用相同的客户信息在同一时刻对相同的方法进行两次调用,那么我将得到约束冲突错误。我原以为saveOrupdate()可以解决这个问题,但事实并非如此。有人可以为这种情况提出解决方案。保存或更新处理对象中的主键属性值,例如,如果新对象的默认值为0,并且新的客户对象的主键属性
保存或更新
处理对象中的主键属性值,例如,如果新对象的默认值为0
,并且新的客户
对象的主键属性设置为0
,则它将始终尝试保存(插入)永远不要尝试更新。它将仅在主键属性为非零值时尝试更新。这就是saveOrUpdate
无法解决问题的原因
我不确定有什么能比处理
unique
约束异常更好。saveOrUpdate的用途完全不同。它用于持久化一个实体,该实体可能已经被持久化(具有一个id和全部),或者可能是一个新id。它与并发访问无关
对于您的问题,有两种选择,称为乐观锁定和悲观锁定
悲观锁定:在检查客户是否存在之前创建一个锁定,因此只有当前线程可以继续,它执行检查并相应地执行操作。具有相同数据的任何其他线程都必须等待第一个线程的更新或插入完成。锁可以在数据库中实现,如果在一台机器上运行,可以使用hibernate或简单的同步块
乐观锁定:你只需像现在一样继续。但是您放置了一个异常处理程序来处理问题中描述的冲突情况
使用同步块可能更容易实现悲观锁定,但它会严重影响性能和可伸缩性。将执行此数据库操作的方法设置为同步可以解决问题吗??就像一次只允许一个线程一样!!因为在方法本身中,您正在检查重复项,
YES
,因为第二个客户对象将被您的重复检查逻辑优雅地过滤掉。通常我们没有这样的检查,在这种情况下,第二次调用仍然会失败。我尝试使该方法同步,但仍然无法帮助错误持续存在。使方法同步使其线程安全对吗?不,当每一条可变信息仅在使用同一监视器的同步块中访问时,您就获得了线程安全。判断一些非平凡的代码是否是线程安全的并不容易。嘿,jens,还有一个疑问!!有一个场景,其中有两个函数,比如f1和f2。f1正在调用函数f2,并且f2已同步。因此,根据您的说法,如果我同时调用函数f1,就不会担心函数f2被同步了,对吗??