Java 弹簧:需要传播。不工作

Java 弹簧:需要传播。不工作,java,spring,spring-mvc,spring-3,spring-transactions,Java,Spring,Spring Mvc,Spring 3,Spring Transactions,我在两个表中插入记录,即Dept和Emp。如果成功创建了Dept表,则仅希望在Emp表中插入记录。另外,如果Emp中的任何插入失败,那么我希望回滚所有事务,其中包括Emp以及Dept表中的回滚 我使用传播尝试了此操作。必需的,如下所示: Java文件 public void saveEmployee(Employee empl){ try { jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getE

我在两个表中插入记录,即
Dept
Emp
。如果成功创建了
Dept
表,则仅希望在
Emp
表中插入记录。另外,如果
Emp
中的任何插入失败,那么我希望回滚所有事务,其中包括
Emp
以及
Dept
表中的回滚

我使用
传播尝试了此操作。必需的
,如下所示:

Java文件

public void saveEmployee(Employee empl){
    try {
        jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(),
                empl.getDeptId(),empl.getAge(),empl.getSex());
    } catch (DataAccessException e) {
        e.printStackTrace();
    }

}

@Transactional(propagation=Propagation.REQUIRED)
public void saveRecords(){
    saveDepartment(dept);
    saveEmployee(empl);     
}
context.xml

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        
    <property name="dataSource" ref="dataSource" />
</bean>

问题:

即使在
Emp
表中插入失败,
Dept
插入也会被持久化,这是我不想要的。我想把所有东西都回滚


请提出建议。

问题在于您的挡块。由于捕获了异常,因此tx不会回滚

您必须抛出异常:

public void saveEmployee(Employee empl){
    try {
        jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(),
                empl.getDeptId(),empl.getAge(),empl.getSex());
    } catch (DataAccessException e) {
        e.printStackTrace();
        throw e;
    }

}
顺便说一下,Progation.Required的语义只是指:如果不存在新的tx,则创建一个新的tx;如果tx正在运行,则使用现有的tx


以下是您对新tx的影响的建议:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void saveEmployee(Employee empl){
    try {
        jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(),
                empl.getDeptId(),empl.getAge(),empl.getSex());
    } catch (DataAccessException e) {
        e.printStackTrace();
        throw e;
    }

}

@Transactional(propagation=Propagation.REQUIRED)
public void saveRecords(){
    saveDepartment(dept);
    try{
       saveEmployee(empl);
    }catch(Exception e){Logger.log("Fail to save emp !");}     
}

查看REQUIRES_NEW效果的关键点是捕获saveEmployee周围的异常。如果未捕获:异常将在另一个tx(输入saveRecords()时启动的tx)中传播,并将回滚。

问题在于捕获块。由于捕获了异常,因此tx不会回滚

您必须抛出异常:

public void saveEmployee(Employee empl){
    try {
        jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(),
                empl.getDeptId(),empl.getAge(),empl.getSex());
    } catch (DataAccessException e) {
        e.printStackTrace();
        throw e;
    }

}
顺便说一下,Progation.Required的语义只是指:如果不存在新的tx,则创建一个新的tx;如果tx正在运行,则使用现有的tx


以下是您对新tx的影响的建议:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void saveEmployee(Employee empl){
    try {
        jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(),
                empl.getDeptId(),empl.getAge(),empl.getSex());
    } catch (DataAccessException e) {
        e.printStackTrace();
        throw e;
    }

}

@Transactional(propagation=Propagation.REQUIRED)
public void saveRecords(){
    saveDepartment(dept);
    try{
       saveEmployee(empl);
    }catch(Exception e){Logger.log("Fail to save emp !");}     
}

查看REQUIRES_NEW效果的关键点是捕获saveEmployee周围的异常。如果未捕获:异常将在另一个tx(输入saveRecords()时启动的tx)中传播,它也将回滚。

您正在捕获异常…您正在捕获异常…上述解决方案有效。出于测试目的,我在
saveEmployee
方法的顶部添加了
@Transactional(propagation=propagation.REQUIRES_NEW)
,以查看其工作原理。我的期望是:
Dept
记录将被保存,
Emp
记录不会被保存,因为
NEW
将创建一个新事务。但我惊讶地看到输出:既没有保存
Dept
也没有保存
Emp
记录。我错过什么了吗?请解释一下。为什么这个案例中没有抛出异常?是因为我们没有任何东西可以回滚吗?还有,为什么我的代码不起作用?调用
saveEmployee
方法时,try块有什么区别?请advice@user182944请参见我的编辑;-)有了这个示例代码,我想你会看到,即使Emp insert失败,dept也会被保存。是的,现在它可以工作了。但我不明白为什么try块会产生这种差异。你能解释一下吗?谢谢你的解释,它有帮助:)上述解决方案工作了。出于测试目的,我在
saveEmployee
方法的顶部添加了
@Transactional(propagation=propagation.REQUIRES_NEW)
,以查看其工作原理。我的期望是:
Dept
记录将被保存,
Emp
记录不会被保存,因为
NEW
将创建一个新事务。但我惊讶地看到输出:既没有保存
Dept
也没有保存
Emp
记录。我错过什么了吗?请解释。为什么在这种情况下不抛出异常?是因为我们没有任何东西可以回滚吗?还有,为什么我的代码不起作用?调用
saveEmployee
方法时,try块有什么区别?请advice@user182944请参见我的编辑;-)有了这个示例代码,我想你会看到,即使Emp insert failyes现在工作了,dept也会被保存……但我不明白为什么try块会产生这种差异……你能解释一下吗?谢谢你的解释,它很有帮助:)