我在几个表中插入记录,即Dept
和Emp
。如果Dept
表成功创建,那么只有我想在Emp
表中插入记录。此外,如果Emp
中的任何插入失败,那么我想回滚所有事务,包括从Emp
和Dept
表的回滚。
我尝试使用Propagation.REQUIRED
,如下所示:
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
的插入也会被持久化,这是我不想要的。我想要回滚所有内容
请建议。
问题是你的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;
}
}
顺便说一下,传播的语义。Required的意思是:如果tx不存在,创建一个新的tx;如果tx正在运行,则使用一个现有的tx。
在你的评论之后,这里有一个建议,看看NEW 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()时开始),它也将回滚。