java - Hibernate 和线程修改同一实体

标签 java multithreading hibernate jpa

我在不同线程中使用相同的实体,并且收到一个optimisticlockexception。我认为就我而言,必须避免这种异常(exception)。情况如下:

我有以下 A 类:

public class A{
    List<B> b;
    List<C> c;

    public void addinListB(B elem){
        b.add(elem);
    }            

    public void addinListC(C elem){
        c.add(elem);
    }

}

然后,我有 SomeObject 类,它使用和修改 A 类。 SomeObject 是:

public class SomeObject {
    private static final Object lock = new Object(); 

    public A search( String idA ){
            synchronized (lock) {
                A a = null;
                try{
                    a = (A) getPersistenceContext()
                        .createQuery("from A where "+ id = :id ")
                        .setParameter("id", id).getSingleResult();
                }catch (NoResultException  e) {
                        A = new A();
                        getPersistenceContext().persist(bday);
                        getPersistenceContext().flush();
                    }
                }
                return a;
            }
    }


    @Transactional
    public someMethodB(){
        A a = search(1);
        B b = new B();
        a.addBinListB(B);
    }


    @Transactional
    public someMethodC(){
        A a = search(1);
        C c = new c();
        a.addCinListC(c);
    }
}

所以,问题如下: 我们有 2 个线程同时运行,一个正在执行“someMethodB(1)”,另一个正在执行“someMethodC(1)”寻找相同的 A id。 假设: id = 1 的 A 不存在: 这意味着第一个赢得锁的人将创建 A 实例,而另一个人将使用它。导致两个线程中同时修改相同的附加对象。因此,当第一个线程提交事务时,刷新已完成,但当第二个线程提交时,将引发乐观锁定异常。

在这种情况下是否可以避免乐观锁异常?我知道A对象正在“修改”添加两个不同的对象(B和C),但我们可以意识到A对象是数据库中的一个对象,只有两个线程都在指向A的不同表中添加新对象。

有没有办法同时修改A实体(向A添加多个B和C对象)并避免optimisticlockException

问候

最佳答案

Hibernate 有一个未广泛记录的选项,在该选项中,只要不修改相同的字段,您就可以同时修改保留隔离的同一实体。当然这可能会与业务语义发生冲突,因此采用时必须非常小心。由于您正在修改 A 中的不同集合,我想它适合您的情况。

乐观锁=“脏”

如何启用它?好吧,这不是 JPA 标准,因此您必须使用 hibernate @Entity 注释并添加属性 optimisticLock='dirty'

参见Hibernate docs , redhat ,还有this link这解释了它(虽然它使用xml配置 - 但效果是相同的)

使用风险自负!

关于java - Hibernate 和线程修改同一实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28862833/

相关文章:

Java nio AclEntry。如何知道主体是组还是用户

javax.ws.rs.WebApplicationException : javax. xml.bind.JAXBException 与链接异常类 [Ljava.lang.Object;

java - 运行 getDisplayMetrics() 方法时,使用 gradle 编译给出的值与使用 eclipse 编译的值不同

python - Python 2.5 中的线程问题,KeyError : 51, 帮助调试吗?

java - 重新附加未执行 SQL 查询的分离实体

java - Tomcat 在 webapp 启动期间挂起

java - 当Android方法被贬值时我该怎么办?

java - 线程的意外行为

android - 实现用于更新 UI 的监听器接口(interface)的主要 Activity

java - 使用 @JoinTable 的 Hibernate 一对多映射问题