【一】事务传播的级别:按照对事务要求的程度,从低--->高可以分成下面7个级别
PROPAGATION_NEVER
总是非事务地执行,如果存在一个活动事务,则抛出异常
PROPAGATION_NOT_SUPPORTED
总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_SUPPORTS
如果没有事务,则非事务的执行。如果存在一个事务,则加入当前事务。
PROPAGATION_REQUIRED
如果没有事务,则开启一个新的事务。如果存在一个事务,则加入当前事务。
PROPAGATION_NESTED
如果没有活动事务, 则按PROPAGATION_REQUIRED 属性执行,如果一个活动的事务存在,则运行在一个嵌套的事务中.
PROPAGATION_REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
PROPAGATION_MANDATORY
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
【二】PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:
PROPAGATION_REQUIRES_NEW每次开启一个新的事务,同时挂起前一个正在运行的事务,开启的新事务会独立提交/回滚。之后被挂起的前一个事务继续运行,在结束时提交或回滚。
由此看来,当使用PROPAGATION_REQUIRES_NEW时,服务层的内部其实是由多个独立的小事务组成的一个大的事务。每个小事务彼此独立,互不影响。一旦内层事务进行了提交,外层事务不能对其进行回滚。而且它需要JTA事务管理器的支持。
PROPAGATION_NESTED并不开启新的事务,它使用save point来代替事务,它可以选择在自己的逻辑内回滚,但它不能在自己的逻辑内提交,而必须等到外层的逻辑提交时一并提交。
由此看来,当使用PROPAGATION_NESTED时,服务层的内部只有一个事务存在,内嵌的事务回滚不会引起外层的事务回滚(如同上面说的,它可以在自己的逻辑内回滚),但外层的事务回滚会引起内嵌的事务回滚(因为内嵌的事务必须等到外层事务提交时才一并提交)。需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。
【三】PROPAGATION_XXX的设置和性能优化
一般来说,PROPAGATION_REQUIRED的传播级别就已经够了。对于长时间、可分段的任务,如果也采用一个大的事务一次性提交,则一旦失败代价太大了。最典型的例子就是:大批量的数据导入,你总不能因为一条数据错了而将其它插入全部回滚吧!
这时可以考虑划分为小段的PROPAGATION_REQUIRED事务进行,多次独立提交事务。
也考虑考虑设置为PROPAGATION_NESTED,因为JDBC 3.0提供了save point机制,可以在事务未提交的情况下保存事务中间的状态,一旦回滚不会回滚全部,而是只回滚到save point点(根据时间)。那么我们可以把大的事务划分成多个小的内嵌事务,每个内嵌事务执行成功后刷新save point,如果全部成功则一次性提交,如果中间失败了则回滚则上一个save point,同时继续下一个内嵌事务,不怕将前面尚未提交的其它事务操作全部回滚。
和PROPAGATION_REQUIRED相比,好处就是事务提交的次数少了,可以一次性写入
posted on 2010-03-15 11:09
Paul Lin 阅读(2596)
评论(0) 编辑 收藏 所属分类:
J2EE 框架