首页 > 解决方案 > @Transactional 和可序列化级别问题

问题描述

我对 JPA 中的隔离级别有疑问。例如我有以下代码:

@Transactional(isolation = Isolation.SERIALIZABLE)
public void first() {
    Obj obj = new Obj();
    obj.setName("t");
    objDAO.save(obj);
    second();
}

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
public void second(){
    List<Obj> objs = objDAO.findAll();
}

在我看来,第二种方法不应该首先看到未提交的更改。因此,名称为“t”的新对象在提交之前不应该可见(但确实如此)。如果我错了,那么请在 JPA 中给我一个不可见的例子。非常感谢您的任何建议。

标签: jpaisolation-level

解决方案


如果您的方法在一个类中,它将不起作用,因为容器会将其视为单个事务。容器不知道您要创建新事务。

来自 Spring 参考:

注意:在代理模式(默认)下,只有通过代理传入的“外部”方法调用会被拦截。这意味着“自调用”,即目标对象中的方法调用目标对象的其他方法,即使调用的方法标有@Transactional,在运行时也不会导致实际事务!

如果你想在新事务中调用方法 second() 你可以试试这个:

@Autowired
private ApplicationContext applicationContext;

@Transactional(isolation = Isolation.SERIALIZABLE)
public void first() {
    Obj obj = new Obj();
    obj.setName("t");
    objDAO.save(obj);
    applicationContext.getBean(getClass()).second();
}

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
public void second(){
    List<Obj> objs = objDAO.findAll();
}

推荐阅读