2007年4月6日星期五

续论spring的事务模型

除了嵌套事务之外,spring另外一个重要的事务模式就是“新建事务” -ROPAGATION_REQUIRES_NEW

当用这个关键词修饰manger的方法时,spring会无视现有session的事务状态,新建一个事务并依照常规提交或者回滚。而原有session会被挂起,当然,其中的修改对新事务来说也是不可见的

这个模式一般用来维护日志表,状态表之类无论对错都必须更新的表单,可以保证即使业务事务回滚,日志维护也能够正常进行。如果不使用这个模式,而和业务事务共用session,一旦业务回滚,整个事务session都会被置为rollback-only而无法提交。

注意:
业务事务不要和新事务处于嵌套状态,也就是说,形如

//配置为new事务模型
doNewSessionMethod(){
try{
//执行业务过程,并提交
mang. doCommMethod();
}catch(e){
//执行失败,回滚业务过程,此时,finally中的业务也无法提交
……
}finally{
//执行日志过程
doLog();
}
}

这样的代码,不会被正确执行
即使你在doNewSession×配置了新事务的模式,而在doComm配置了标准事务模型

因为标准事务模型,即PROPAGATION_REQUIRED的工作模式是如果存在事务,则复用事务,否则,新建j事务,当他嵌套在new事务中时,就会复用外部事务,如果在业务过程触发了回滚,
和其处在同一事务中的日志过程也是无法提交的

正确的用法应该是:
//常规调用,不挂靠事务处理
doMethod(){
try{
//执行业务过程,并提交
mang. doCommMethod();
}catch(e){
业务过程失败,回滚
……
}finally{
//无论业务事务是否成功
//启动新事务,并执行日志过程,提交
mang.doNewTranLog();
}
}

这样,无论业务成功与否,日志维护都会正常提交。

在transanceManger中的配置方式略