Spring之Transactional注解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之Transactional注解相关的知识,希望对你有一定的参考价值。

参考技术A

该注解的签名如下:

定义零(0)个或多个异常类,这些异常类必须是Throwable的子类,指示哪些异常类型必须导致事务回滚。
默认情况下,事务将在RuntimeException和Error上回滚,但不会在检查型异常(业务异常)上回滚。具体可以看DefaultTransactionAttribute.rollbackOn(Throwable)方法,有比较详细的解释。
这是构造回滚规则(与 rollbackForClassName比较)的首选方法,它匹配异常类及其子类。

定义零(0)个或多个异常名称(对于必须是Throwable子类的异常),指示哪些异常类型必须导致事务回滚。
这可以是完全限定类名的子字符串,目前不支持通配符。例如,“ServletException”的值将与ServletException及其子类匹配。

定义零(0)个或多个异常类,这些异常类必须是Throwable的子类,指示哪些异常类型不能导致事务回滚。
这是构造回滚规则(与noRollbackForClassName相比)的首选方法,它匹配异常类及其子类。

一个布尔标志,如果事务实际上是只读的,则可以将其设置为true,从而允许在运行时进行相应的优化。
默认为false。
这只是作为实际事务子系统的提示;它不一定会导致写入访问尝试失败。无法解释只读提示的事务管理器在请求只读事务时不会引发异常,而是默默地忽略该提示。

此事务的超时时间(秒)。
默认为基础事务系统的默认超时。为Propagation.REQUIRED和Propagation.REQUIRES_NEW设计的参数,因为它只适用于新启动的事务。默认值为-1,表示不设置超时时间。

此事务的超时时间(秒)。
默认为基础事务系统的默认超时。
专门设计用于Propagation.REQUIRED和Propagation.REQUIRES_NEW,因为它只适用于新启动的事务。

事务隔离级别。
默认为Isolation.DEFAULT.
专门为Propagation.REQUIRED 和 Propagation.REQUIRES_NEW设计使用的,因为它只适用于新启动的事务。如果您希望隔离级别声明在参与具有不同隔离级别的现有事务时被拒绝,请考虑在事务管理器上切换“验证有效事务”标志为“true”。

事务传播类型。
默认为 Propagation.REQUIRED.

定义零(0)个或多个事务标签。标签可用于描述事务 ,并可由单个事务管理器进行评估。标签可能仅用于描述目的,或映射到预定义的事务管理器特定选项。
请参阅实际事务管理器实现的描述,了解它如何评估事务标签。

指定事务的限定符值。
可用于确定目标事务管理器,与特定TransactionManager bean定义的限定符值(或bean名称)匹配。

propagation的取值定义成了一个枚举类,如下所示:

REQUIRED
其值为0,支持当前事务,如果不存在,则创建新事务。类似于同名的EJB事务属性。这是事务注解的默认设置。

SUPPORTS
其值为1,支持当前事务,如果不存在,则以非事务方式执行。类似于同名的EJB事务属性。
注意:对于具有事务同步的事务管理器,SUPPORTS 与完全没有事务略有不同,因为它定义了同步将应用的事务范围。因此,相同的资源(JDBC连接、Hibernate会话等)将在整个指定范围内共享。请注意,这取决于事务管理器的实际同步配置。

MANDATORY
支持当前事务,如果不存在则抛出异常。类似于同名的EJB事务属性。

REQUIRES_NEW
创建新事务,并暂停当前事务(如果存在)。类似于同名的EJB事务属性。
注意:实际的事务暂停不会在所有交易管理器上立即生效。这尤其适用于JtaTransactionManager。JtaTransactionManager,它需要TransactionManager 可供其使用(在标准Java EE中是特定于服务器的)。

NOT_SUPPORTED
以非事务方式执行,如果当前事务存在,则暂停当前事务。类似于同名的EJB事务属性。
注意:实际的事务暂停不会在所有事务管理器上立即生效。这尤其适用于JtaTransactionManager。JtaTransactionManager,它需要TransactionManager可供其使用(在标准Java EE中是特定于服务器的)。

NEVER
以非事务方式执行,如果存在事务,则抛出异常。类似于同名的EJB事务属性。

NESTED
如果存在当前事务,则在嵌套事务中执行,否则按要求执行。EJB中没有类似的特性。
注意:嵌套事务的实际创建只适用于特定的事务管理器。开箱即用,这只适用于JDBC DataSourceTransactionManager。一些JTA提供者可能也支持嵌套事务。

枚举,用来表示Transactional 注解的事务隔离级别,与TransactionDefinition 接口定义的事务隔离级别相一致。
枚举定义如下:

DEFAULT
使用基础数据存储的默认隔离级别。所有其他级别都对应于JDBC隔离级别。

READ_UNCOMMITTED
一个常数,指示可能发生脏读、不可重复读和幻象读。此级别允许一个事务更改的行在提交该行的任何更改之前被另一个事务读取(“脏读”)。如果回滚了任何更改,则第二个事务将检索到无效行。

READ_COMMITTED
指示防止脏读的常数;可能会发生不可重复读取和幻象读取。此级别仅禁止事务读取包含未提交更改的行。

REPEATABLE_READ
指示防止脏读和不可重复读的常数;可能会发生幻象读取。该级别禁止事务读取包含未提交更改的行,还禁止一个事务读取一行,第二个事务更改该行,第一个事务重新读取该行,第二次获得不同的值(“不可重复读取”)。

SERIALIZABLE
一个常数,指示防止脏读、不可重复读和幻象读。该级别包括隔离可重复读取的禁止,并进一步禁止一个事务读取满足where条件的所有行,第二个事务插入满足where条件的行,第一个事务重新读取相同条件,在第二次读取中检索附加的“幻影”行。

Spring 之注解事务 @Transactional

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,

它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

事务传播行为类型

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。

 

 

复制代码
spring 事务注解

默认遇到throw new RuntimeException("...");会回滚
需要捕获的throw new Exception("...");不会回滚

// 指定回滚
@Transactional(rollbackFor=Exception.class) 
    public void methodName() {
       // 不会回滚
       throw new Exception("...");
    } 
//指定不回滚
@Transactional(noRollbackFor=Exception.class)
    public ItimDaoImpl getItemDaoImpl() {
        // 会回滚
        throw new RuntimeException("注释");
    } 

    // 如果有事务,那么加入事务,没有的话新建一个(不写的情况下)
    @Transactional(propagation=Propagation.REQUIRED) 
    // 容器不为这个方法开启事务
    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    // 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
    @Transactional(propagation=Propagation.REQUIRES_NEW) 
    // 必须在一个已有的事务中执行,否则抛出异常
    @Transactional(propagation=Propagation.MANDATORY)
    // 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
    @Transactional(propagation=Propagation.NEVER) 
    // 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
    @Transactional(propagation=Propagation.SUPPORTS) 
    
    /*
    public void methodName(){
       // 本类的修改方法 1
       update();
       // 调用其他类的修改方法
       otherBean.update();
       // 本类的修改方法 2
       update();
    }
    other失败了不会影响 本类的修改提交成功
    本类update的失败,other也失败
    */
@Transactional(propagation=Propagation.NESTED) 
// readOnly=true只读,能插入,但不能更新,删除 
@Transactional (propagation = Propagation.REQUIRED,readOnly=true) 
// 设置超时时间
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 设置数据库隔离级别
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)

复制代码

 

资料:http://my.oschina.net/guanzhenxing/blog/214228

 
 

以上是关于Spring之Transactional注解的主要内容,如果未能解决你的问题,请参考以下文章

Spring学习之事务注解@Transactional

Spring 之注解事务 @Transactional

Spring 之@Transactional篇

spring @Transactional 事务注解的坑

如何在 Spring Boot 中使用 @Transactional 注解

Spring @Transactional 和 Spring @Lock 注解有啥关系?