首页 > 解决方案 > 事务不会因 RuntimeException 而回滚

问题描述

我目前有一个类似于下面的代码,但它的行为不符合预期。我的假设是父母Person会被保存,但孩子Person应该被回滚。

但这并没有发生。两个人都保存在数据库中。

有人可以解释一下为什么会这样以及如何使其按计划运行吗?

/**
 * This will create one physical transaction PT1, and within a logical transaction LT1.
 */
@Transactional(propagation = Propagation.REQUIRED)
public void insertParentPerson() {
    System.out.println(getCurrentMethod());
    
    final Person person = getNewPerson();

    save(person);
    
    try {
        insertChildPerson();
    } catch (NoSuchElementException noSuchElementException) {
        System.out.println("Catching child exception");
    }
}

/**
 * This transaction lives in the same physical transaction (PT1) as its parent but has an own logical transaction LT2
 */
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertChildPerson() {
    System.out.println(getCurrentMethod());

    final Person person = getNewPerson();

    save(person);

    throw new NoSuchElementException("Random Exception");
}

标签: javaspringspring-data

解决方案


首先,该方法没有抛出异常,因此 insertParentPerson() 正常结束,因此正常提交事务。

其次,第二个方法上的@Transactional注解在从同一个类调用该方法时不考虑,而仅在从外部调用时才考虑(因为此时不调用代理类)


推荐阅读