Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring事务传播和乐观锁定问题_Java_Spring_Hibernate_Spring Transactions_Optimistic Locking - Fatal编程技术网

Java Spring事务传播和乐观锁定问题

Java Spring事务传播和乐观锁定问题,java,spring,hibernate,spring-transactions,optimistic-locking,Java,Spring,Hibernate,Spring Transactions,Optimistic Locking,我有一个外部方法调用内部方法的设置。此内部方法可能会引发异常,导致其回滚。我不希望此异常影响外部方法。为了实现这一点,我在内部方法上使用了@Transactional(propagation=propagation.REQUIRED\u NEW) 以下是我的代码的简化版本: public class ServiceAImpl implements ServiceA{ @Autowired private ServiceB serviceB; @Transactional

我有一个外部方法调用内部方法的设置。此内部方法可能会引发异常,导致其回滚。我不希望此异常影响外部方法。为了实现这一点,我在内部方法上使用了@Transactional(propagation=propagation.REQUIRED\u 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\u new,它们现在包含在自己的方法中 单独交易。如果内部方法遇到异常,它将回滚,但不会导致外部方法回滚

当外部方法运行时,它调用内部方法。外部方法在运行内部方法时暂停。一旦内部方法完成,它将自 这是另一种交易。外部方法取消暂停。并且它也作为另一个事务提交

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

我的问题是: 有没有办法防止外部方法触发乐观锁定

我感到惊讶的是,外部方法甚至试图将更改提交给子类。我假设,由于内部方法 包含在自己的事务中,外部方法的事务将不再包括updateChild方法


我将Spring3.0.5与Hibernate3.6.10结合使用,假设您正在使用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);

一个简单的解决方案是从外部方法捕获内部方法的乐观锁异常,并使其通过该异常。内部方法无例外地更新数据库记录。另外,我认为捕获并忽略乐观锁是不明智的,如果通过并发用户更新引发真正的乐观锁异常,我就完蛋了。你的传播是正确的。在外部事务上使用Propagation.REQUIRED和在内部事务上使用Propagation.REQUIRED\u NEW不会影响内部事务的任何提交/回滚的外部事务。请确定您的哪些行在操作期间正在修改。我认为您在两个事务中使用的是同一行,版本字段正在更新,并且引发了OptimisticLockException。嗨,Tanjim,他们肯定在更新数据库中的同一行。那么您必须在提交内部事务后获得最新版本的行,并在第二个事务中使用该版本更新同一行。否则您将得到OptimisticLockException。嗨,Tanjim,不幸的是,merge没有解决问题。尽管如此,我还是很感谢你的帮助。显然,合并并不是解决问题的关键。关键是,当您第二次更新行时,只需使用更新版本,这是避免优化锁定异常的唯一方法。