2014-06-28 55 views
1

我在几张表中插入记录,即DeptEmp。如果Dept表成功创建,那么只需要在Emp表中插入记录。另外,如果Emp中的任何插入失败,那么我想要回滚所有包含从Emp以及Dept表中回滚的事务。Spring:Propagation.REQUIRED not working

这个我试过用Propagation.REQUIRED如下图所示:

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插入正在持续,我不想。我想回滚一切。

请建议。

+1

您正在捕捉异常... –

回答

4

问题是你的catch块。由于异常被捕获,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的效果:

@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()时启动的异常),它也会回滚。

+0

上述解决方案奏效。仅用于测试目的,我在'saveEmployee'方法的顶部添加了@Transactional(propagation = Propagation.REQUIRES_NEW),以查看它的工作原理。我的期望是:'Dept'记录将被保存,'Emp'记录将不会被保存,因为'NEW'会创建一个新的事务。但我很惊讶地看到输出结果:“Dept”和“Emp”记录都没有保存。我错过了什么吗?请解释。 – user182944

+0

为什么在这种情况下不引发异常?是因为我们没有任何东西可以回滚?另外,为什么我的代码片段不起作用? try块在调用saveEmployee方法时有什么不同?请咨询 – user182944

+0

@ user182944看看我编辑过的编辑;-)通过这个示例代码,我认为即使当empl插入失败时,您也会看到该部门将被保存 – ben75