[转]Spring----Spring的事务传播级别和事务性能优化

[转]Spring----Spring的事务传播级别和事务性能优化

出自:http://www.blogjava.net/pengpenglin/archive/2010/03/15/315445.html

【一】事务传播的级别:按照对事务要求的程度,从低--->高可以分成下面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并不开启新的事务,它使用savepoint来代替事务,它可以选择在自己的逻辑内回滚,但它不能在自己的逻辑内提交,而必须等到外层的逻辑提交时一并提交。

由此看来,当使用PROPAGATION_NESTED时,服务层的内部只有一个事务存在,内嵌的事务回滚不会引起外层的事务回滚(如同上面说的,它可以在自己的逻辑内回滚),但外层的事务回滚会引起内嵌的事务回滚(因为内嵌的事务必须等到外层事务提交时才一并提交)。需要JDBC3.0以上驱动及1.4以上的JDK版本支持。

【三】PROPAGATION_XXX的设置和性能优化

一般来说,PROPAGATION_REQUIRED的传播级别就已经够了。对于长时间、可分段的任务,如果也采用一个大的事务一次性提交,则一旦失败代价太大了。最典型的例子就是:大批量的数据导入,你总不能因为一条数据错了而将其它插入全部回滚吧!

这时可以考虑划分为小段的PROPAGATION_REQUIRED事务进行,多次独立提交事务。

也考虑考虑设置为PROPAGATION_NESTED,因为JDBC3.0提供了savepoint机制,可以在事务未提交的情况下保存事务中间的状态,一旦回滚不会回滚全部,而是只回滚到savepoint点(根据时间)。那么我们可以把大的事务划分成多个小的内嵌事务,每个内嵌事务执行成功后刷新savepoint,如果全部成功则一次性提交,如果中间失败了则回滚则上一个savepoint,同时继续下一个内嵌事务,不怕将前面尚未提交的其它事务操作全部回滚。

和PROPAGATION_REQUIRED相比,好处就是事务提交的次数少了,可以一次性写入

相关推荐