我在几个表中插入记录,即Dept
和Emp
。如果成功创建了Dept
表,那么我只想在Emp
表中插入记录。此外,如果Emp
中的任何插入失败,那么我想回滚所有包含来自Emp
和Dept
表的回滚的事务。
我使用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
插入也会保持不变,这是我不想要的。我想要回滚一切。
请建议。
答案 0 :(得分:4)
问题是你的阻塞。由于异常被捕获,因此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。
在您的评论之后,建议您查看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()时启动的那个)中传播,它也会回滚。