两者都用于内嵌事务:在一个事务方法内嵌套调用另一个事务。
但是NESTED是可以回滚到保存点的,即要么选择提交调用方的数据,要么选择把调用方数据回滚(当然被掉用方肯定回滚了)到保存点,或者全部回滚
而REQUIRES_NEW是要么选择提交调用方的数据,要么选择把调用方数据回滚(当然被掉用方肯定回滚了)。
例题:
调用方方法:Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public Session saveDepartment(Department dep, User u, UserDao userDao) {
this.getJdbcTemplate().execute("update departments set name='"+dep.getName()+"' where id="+dep.getId()+"");
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.getDataSource());
Connection conn=conHolder.getConnection();
Savepoint sp=null;
try {
System.out.println("Connection.getMetaData().supportsSavepoints() "+conn.getMetaData().supportsSavepoints());
System.out.println("departments conn hashcode="+conn.hashCode()+"departments conn is closed:"+conn.isClosed());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// System.out.print(conn.getMetaData());
sp=conn.setSavepoint();
this.getJdbcTemplate().execute("update departments set name='999"+dep.getName()+"' where id="+dep.getId()+"");
userDao.saveUser(u); //嵌套调用userdao的方法
} catch (Exception e) {
try {
conn.rollback(sp);//saveUser为Propagation.NESTED时,回滚到保存点,当然也可以全部回滚rollback()
//conn.rollback();//saveUser为Propagation.REQUIRES_NEW时,全部回滚rollback(),或者提交调用方的数据commit();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return null;
}
@Transactional(readOnly = false, propagation = Propagation.NESTED)
public void saveUser(User user) {
this.getJdbcTemplate().execute("update users set first_name='"+user.getName().getFirstName()+"' where id="+user.getId()+" ");
System.out.println("saveuser return ");
return;
}