Spring Transaction Propagation和乐观锁定的问题

时间:2015-12-08 03:45:27

标签: java spring hibernate spring-transactions optimistic-locking

我有一个外部方法调用内部方法的设置。这个内部方法可能抛出一个异常,导致它回滚。我不希望此异常影响外部方法。为实现这一点,我在内部方法上使用了@Transactional(propagation = Propagation.REQUIRED_NEW)。

以下是我的代码的简化版本:

public class ServiceAImpl implements ServiceA{
    @Autowired
    private ServiceB serviceB;

    @Transactional(propagation=Propagation.REQUIRED)
    public void updateParent(Parent parent) {
        update(parent);
        serviceB.updateChild(parent);
    }
}

public class ServiceBImpl implements ServiceB {
    @Transactional(propagation=Propagation.REQUIRED_NEW)
    public void updateChild(Parent parent) {
        checkIfChildHasErrors(parent.getChild()); //throws RuntimeException if Child has errors
        update(parent.getChild());
    }
}

public class Parent {
    @Version
    private Integer version;
    private Child child;

    //insert getters and setters
}

public class Child {
    @Version
    private Integer version;

    //insert getters and setters
}

我仍然是传播的新手但是从我的理解,因为外部方法(updateParent)有Propagation.REQUIRED而内部方法(updateChild)有Propagation.REQUIRED_NEW,它们现在包含在他们自己的 单独的交易。如果内部方法遇到异常,它将回滚但不会导致外部方法回滚。

当外部方法运行时,它调用内部方法。在运行内部方法时,外部方法暂停。一旦内部方法完成,它就会被提交 这是一个不同的交易。外部方法取消暂停。它也是另一项交易。

我遇到的问题是提交外部方法的过程是触发Child类的乐观锁定(可能是因为版本的值 内部方法结束并提交后,字段已更改)。由于外部方法的Child实例已经过时,因此提交它会触发乐观锁定。

我的问题是: 有没有办法阻止外部方法触发优化锁定?

我很惊讶外部方法甚至尝试将更改提交给Child类。我假设自内部方法 包含在自己的事务中,外部方法的事务将不再包含updateChild方法。

我正在使用带有Hibernate 3.6.10的Spring 3.0.5

1 个答案:

答案 0 :(得分:0)

假设您使用merge进行更新

对于内部交易

Entity entityUpdated = entityManager.merge(entity);

对于外部交易

if (entityUpdated != null){
    // if inner transaction rolledback entityUpdated will be null. Condition will save u from nullPointerException
    outerEntity.setVersion(entityUpdated.getVersion);
}

entityManager.merge(outerEntity);