引言: 在Spring中@Transactional提供一种控制事务管理的快捷手段,但是很多人都只是@Transactional简单使用,并未深入了解,其各个配置项的使用方法,本文将深入讲解各个配置项的使用。

1.  @Transactional的定义

Spring中的@Transactional基于动态代理的机制,提供了一种透明的事务管理机制,方便快捷解决在开发中碰到的问题。在现实中,实际的问题往往比我们预期的要复杂很多,这就要求对@Transactional有深入的了解,以来应对复杂问题。

首先我们来看看@Transactional的代码定义:

  1. @Target({ElementType.METHOD, ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Inherited
  4. @Documented
  5. public @interface Transactional {
  6. /**
  7. * A qualifier value for the specified transaction.
  8. * <p>May be used to determine the target transaction manager,
  9. * matching the qualifier value (or the bean name) of a specific
  10. * {@link org.springframework.transaction.PlatformTransactionManager}
  11. * bean definition.
  12. */
  13. String value() default "";
  14. /**
  15. * The transaction propagation type.
  16. * Defaults to {@link Propagation#REQUIRED}.
  17. * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
  18. */
  19. Propagation propagation() default Propagation.REQUIRED;
  20. /**
  21. * The transaction isolation level.
  22. * Defaults to {@link Isolation#DEFAULT}.
  23. * @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel()
  24. */
  25. Isolation isolation() default Isolation.DEFAULT;
  26. /**
  27. * The timeout for this transaction.
  28. * Defaults to the default timeout of the underlying transaction system.
  29. * @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout()
  30. */
  31. int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
  32. /**
  33. * {@code true} if the transaction is read-only.
  34. * Defaults to {@code false}.
  35. * <p>This just serves as a hint for the actual transaction subsystem;
  36. * it will <i>not necessarily</i> cause failure of write access attempts.
  37. * A transaction manager which cannot interpret the read-only hint will
  38. * <i>not</i> throw an exception when asked for a read-only transaction.
  39. * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()
  40. */
  41. boolean readOnly() default false;
  42. /**
  43. * Defines zero (0) or more exception {@link Class classes}, which must be a
  44. * subclass of {@link Throwable}, indicating which exception types must cause
  45. * a transaction rollback.
  46. * <p>This is the preferred way to construct a rollback rule, matching the
  47. * exception class and subclasses.
  48. * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}
  49. */
  50. Class<? extends Throwable>[] rollbackFor() default {};
  51. /**
  52. * Defines zero (0) or more exception names (for exceptions which must be a
  53. * subclass of {@link Throwable}), indicating which exception types must cause
  54. * a transaction rollback.
  55. * <p>This can be a substring, with no wildcard support at present.
  56. * A value of "ServletException" would match
  57. * {@link javax.servlet.ServletException} and subclasses, for example.
  58. * <p><b>NB: </b>Consider carefully how specific the pattern is, and whether
  59. * to include package information (which isn't mandatory). For example,
  60. * "Exception" will match nearly anything, and will probably hide other rules.
  61. * "java.lang.Exception" would be correct if "Exception" was meant to define
  62. * a rule for all checked exceptions. With more unusual {@link Exception}
  63. * names such as "BaseBusinessException" there is no need to use a FQN.
  64. * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}
  65. */
  66. String[] rollbackForClassName() default {};
  67. /**
  68. * Defines zero (0) or more exception {@link Class Classes}, which must be a
  69. * subclass of {@link Throwable}, indicating which exception types must <b>not</b>
  70. * cause a transaction rollback.
  71. * <p>This is the preferred way to construct a rollback rule, matching the
  72. * exception class and subclasses.
  73. * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}
  74. */
  75. Class<? extends Throwable>[] noRollbackFor() default {};
  76. /**
  77. * Defines zero (0) or more exception names (for exceptions which must be a
  78. * subclass of {@link Throwable}) indicating which exception types must <b>not</b>
  79. * cause a transaction rollback.
  80. * <p>See the description of {@link #rollbackForClassName()} for more info on how
  81. * the specified names are treated.
  82. * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}
  83. */
  84. String[] noRollbackForClassName() default {};
  85. }

基于源代码,我们可以发现在@Transactional,原来有这么多的属性可以进行配置,从而达到复杂应用控制的目的。具体各个属性的用法和作用,将在本文的后面逐一进行讲解和说明。

2.  使用@Transactional的Spring配置

为了使用基于@Transactional的事务管理,需要在Spring中进行如下的配置:

  1. <beans:bean id="transactionManager"
  2. class="org.springframework.orm.jpa.JpaTransactionManager">
  3. <beans:property name="dataSource" ref="dataSource" />
  4. <beans:property name="entityManagerFactory" ref="entityManagerFactory" />
  5. </beans:bean>
  6. <!-- 声明使用注解式事务 -->
  7. <tx:annotation-driven transaction-manager="transactionManager" />

dataSource是在Spring配置文件中定义的数据源的对象实例,EntityManagerFactory是基于JPA使用的实体类管理器:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean。这些都是用来配置与数据库的连接信息,本质上,@Transactional使用了JDBC的事务来进行事务控制的。

<annotation-driven>标签的声明,则是在Spring内部启用@Transactional来进行事务管理,类似开关之类的声明。

3.  @Transactional之value

value这里主要用来指定不同的事务管理器;主要用来满足在同一个系统中,存在不同的事务管理器。比如在Spring中,声明了两种事务管理器txManager1, txManager2.

然后,用户可以根据这个参数来根据需要指定特定的txManager.

那有同学会问什么情况下会存在多个事务管理器的情况呢? 比如在一个系统中,需要访问多个数据源或者多个数据库,则必然会配置多个事务管理器的。

4.   @Transactional之propagation

Propagation支持7种不同的传播机制:

  • REQUIRED

业务方法需要在一个事务中运行,如果方法运行时,已处在一个事务中,那么就加入该事务,否则自己创建一个新的事务.这是spring默认的传播行为.。

  • SUPPORTS:

如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分,如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。

  • MANDATORY:

只能在一个已存在事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下调用,就抛异常

  • REQUIRES_NEW

业务方法总是会为自己发起一个新的事务,如果方法已运行在一个事务中,则原有事务被挂起,新的事务被创建,直到方法结束,新事务才结束,原先的事务才会恢复执行.

  • NOT_SUPPORTED

声明方法需要事务,如果方法没有关联到一个事务,容器不会为它开启事务.如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行.

  • NEVER:

声明方法绝对不能在事务范围内执行,如果方法在某个事务范围内执行,容器就抛异常.只有没关联到事务,才正常执行.

  • NESTED:

如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保证点.内部事务回滚不会对外部事务造成影响, 它只对DataSourceTransactionManager 事务管理器起效.

其实大家最感到困惑的是REQUIRED_NEW和NESTED两种不同的传播机制,功能类似,都涉及到了事务嵌套的问题,那两者有何区别呢?该如何正确使用这两种模式呢?

        以下是摘自Spring的文档:
          PROPAGATION_REQUIRES_NEW : uses a completely independent transaction for each affected transaction scope. In that case, the underlying physical transactions are different and hence can commit or roll back independently, with an outer transaction not affected by an inner transaction's rollback status.
         内部的事务独立运行,在各自的作用域中,可以独立的回滚或者提交;而外部的事务将不受内部事务的回滚状态影响。 
        ROPAGATION_NESTED : uses a single physical transaction with multiple savepoints that it can roll back to. Such partial rollbacks allow an inner transaction scope to trigger a rollback for its scope, with the outer transaction being able to continue the physical transaction despite some operations having been rolled back. This setting is typically mapped onto JDBC savepoints, so will only work with JDBC resource transactions.
       NESTED的事务,基于单一的事务来管理,提供了多个保存点。这种多个保存点的机制允许内部事务的变更触发外部事务的回滚。而外部事务在混滚之后,仍能继续进行事务处理,即使部分操作已经被混滚。 由于这个设置基于JDBC的保存点,所以只能工作在JDBC的机制智商。
       由此可知, 两者都是事务嵌套,不同之处在于,内外事务之间是否存在彼此之间的影响;NESTED之间会受到影响,而产生部分回滚,而REQUIRED_NEW则是独立的。

Spring中@Transactional用法深度分析的更多相关文章

  1. Spring中@Transactional用法

    作者:bladestone 来源:CSDN 原文:https://blog.csdn.net/blueheart20/article/details/44654007 版权声明:本文为博主原创文章,转 ...

  2. Spring中@Async用法详解及简单实例

    Spring中@Async用法 引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类 ...

  3. Spring中@Transactional事务回滚

    转载: Spring中@Transactional事务回滚 一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部 ...

  4. (转)Spring中@Async用法总结

     原文:http://blog.csdn.net/blueheart20/article/details/44648667 引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的: ...

  5. Spring中@Async用法总结

    引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3. ...

  6. 透彻的掌握 Spring 中@transactional 的使用

    事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编码式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...

  7. Spring中@Transactional事务回滚实例及源码

    一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除 ...

  8. Spring中@Transactional事务回滚(含实例详细讲解,附源码)

    一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除 ...

  9. Spring中@Transactional(rollbackFor = Exception.class)的作用

    Spring中的@Transactional(rollbackFor = Exception.class)事务处理,当你的方法中抛出异常时,它会将 事务回滚,数据库中的数据将不会改变,也就是回到进入此 ...

随机推荐

  1. POJ 1436 Horizontally Visible Segments

    题意: 有一些平行于y轴的线段 ,两条线段称为互相可见当且仅当存在一条水平线段连接这两条  与其他线段没交点. 最后问有多少组  3条线段,他们两两是可见的. 思路: 线段树,找出两两可见的那些组合, ...

  2. LCA-倍增法(在线)

    原文:http://www.tuicool.com/articles/N7jQV32 1. DFS预处理出所有节点的深度和父节点 inline void dfs(int u) { int i; for ...

  3. comboBox的id返回System.Data.DataRowView

    关系到ComboBox的DataSource,DisplayMember和ValueMember属性的设置顺序的问题. ComboBox的DataSource属性为object类型,但是需要实现ILi ...

  4. UITableViewStyleGrouped 模式下 headview 多出一块高度问题

    self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView ...

  5. Python中的random模块

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

  6. Linux-如何添加路由表

    linux下静态路由修改命令方法一:添加路由route add -net 192.168.0.0/24 gw 192.168.0.1route add -host 192.168.1.1 dev 19 ...

  7. URAL 1519 基础插头DP

    题目大意: 给定一个图,一部分点'*'作为障碍物,求经过所有非障碍点的汉密尔顿回路有多少条 基础的插头DP题目,对于陈丹琦的论文来说我觉得http://blog.sina.com.cn/s/blog_ ...

  8. Codeforces Round #327 (Div. 2)-Wizards' Duel

    题意: 在一条长度为l的走廊,两个人站在走廊的左右两端分别以p,q的速度走来,问他们相遇时离左端的距离是多少? 思路: 非常简单的暴力题,不解释. 代码如下: #include <iostrea ...

  9. Tomcat的安装(一)

    一.Tomcat文件下载类型 1.tar.gz 文件是linux的安装包 2.exe文件是Windows系统的安装包 3.zip文件是Windows系统下压缩版(解压缩即可,免安装) 二.下面使用zi ...

  10. 解决使用IIS5.0配置的FTP服务器,客户端浏览器访问时无法获取目录列表的问题。

    我在windows xp sp3下利用iis构架了FTP服务器,允许且只允许匿名用户登陆.但刚开始配置好后,不管是使用命令行模式还是使用浏览器都发现无法访问. 于是怀疑防火墙屏蔽端口所致,果不其然,在 ...