@Transactional在设置的时候有以下几个主要属性可以设置,

1.propagation:分别为事务的传播行为;

2.isolation:事务的隔离级别;

3.readOnly读写事务控制;

4.timeout:事务的超时时间;

5.rollbackFor:用于指定能够触发事务回滚的异常类型,可以指定多个异常类型;

6.noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型;

一 propagation属性是事务的传播行为,一共有七种,默认的传播行为为REQUIRED,具体各个传播行为的解释如下:

①Propagation.REQUIRED:如果当前事务存在,就加入该事务,如果事务不存在,就重新创建一个新的事务

举例:如果方法A和方法B都添加了注解,在默认传播方式下,A方法内调用B方法,两个方法共用的是同一个事务;如果方法A添加了默认传播方式的注解,B方法没有加注解,此时B方法和A方法也是共用同一个事务;

②PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务就以非事务方式执行;

③PROPAGATION_MANDATORY:使用当前事务,如果当前没有事务,就抛出异常;

④PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,就把当前事务挂起;

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

⑥PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,就抛出异常;

⑦PROPAGATION_NESTED:如果当前存在事务,就创建一个子事务执行,如果当前没有事务则执行和PROPAGATION_REQUIRED 类似的操作。

注意:

1.在使用默认隔离级别Propagation.REQUIRED,当A方法调用B方法,两个方法都使用了默认的隔离级别,A方法里面调用的B方法(有异常抛出)做了try-catch操作,此时所有的方法都在同一个事务,当B方法发生异常,这个方法所在的事务就会被Spring设置成rollback状态,因为异常被捕获,所以外部方法执行完commit操作,发现当前事务已经处于rollback状态,所以会回滚所有的操作。

2.在使用隔离级别为PROPAGATION_NESTED,每个NESTED事务执行前会将当前操作保存下来,叫做保存点,如果当前NESTED事务执行失败,则回滚到之前的保存点,保存点使得子事务的回滚不对主事务造成影响,NESTED事务在外部事务提交以后自己才会提交。

总结:

REQUIRES_NEW 最为简单,不管当前有无事务,它都会开启一个全新事务,既不影响外部事务,也不会影响其他内部事务,真正的井水不犯河水,坚定而独立。

REQUIRED 在没有外部事务的情况下,会开启一个独立的新事务,且不会对其他同级事务造成影响;而当存在外部事务的情况下,则会与外部事务同生共死。

NESTED 在没有外部事务的情况下与 REQUIRED 效果相同;而当存在外部事务的情况下,当外部事务回滚时,它会创建一个嵌套事务(子事务)。外部事务回滚时,子事务会跟着回滚;但子事务的回滚不会对外部事务和其他同级事务造成影响。

具体的案例可以查看博客:https://www.51cto.com/article/712850.html

isolation:事务的隔离级别

脏读:当一个事务读取另一个事务还没有提交的修改是,产生脏读;

不可重复读:同一个查询在同一个事务中多次执行,由于其他事务所做的修改和删除,每次返回的结果不同,此时会发生非重复读;

幻读:同一个查询在同一个事务中多次执行,由于其他事务所做的插入操作,导致每次返回的结果不同,此时会发生幻读;

有以下5种隔离级别:

1.DEFAULT默认级别

DEFAULT为数据库的默认隔离级别;

2.READ_UNCOMMITTED未授权读取级别

这是最低的隔离级别,一个事务能读取到别的事务未提交的更新数据,很不安全,可能出现丢失更新、脏读、不可重复读、幻读。

3.READ_COMMITTED授权读取级别

以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读,但不能防止不可重复读、幻读。

4.REPEATABLE_READ可重复读取级别

保证同一事务中先后执行的多次查询将返回同一结果,不受其他事务影响。以操作同一行数据为前提,读事务禁止其他写事务,但允许其他读事务,未提交的写事务禁止其他读事务和写事务。此隔离级别可以防止更新丢失、脏读、不可重复读,但不能防止幻读。

5.SERIALIZABLE序列化级别

所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。提供严格的事务隔离,此隔离级别可以防止更新丢失、脏读、不可重复读、幻读。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

readOnly读写事务控制

readOnly=true表明所注解的方法或类只是读取数据。

readOnly=false表明所注解的方法或类是增加,删除,修改数据。

四 @Transactional失效场景

1.失效场景一@Transactional 应用在非 public 修饰的方法上

之所以会失效是因为在Spring AOP 代理时,TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,Spring代理工厂在启动时,会扫描所有类和方法,并会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。

2.失效场景二@Transactional 注解属性 propagation 设置错误

这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。

TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

3.失效场景三@Transactional 注解属性 rollbackFor 设置错误

rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了继承自 RuntimeException 的异常或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor属性。

4.失效场景四 同一个类中方法调用,导致@Transactional失效

比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的,这是由于Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

5.失效场景五 异常被你try…catch…了,导致@Transactional失效

Spring容器是根据你方法的抛出的Exception来进行回滚的,如果你代码里自己try…catch 了,并没有抛出异常,就会失效,具体情况还需要具体分析。

6.失效场景六 数据库引擎不支持事务

事务能否生效数据库引擎是支持事务的关键。常用的MySQL数据库默认使用支持事务的innodb引擎。如果数据库引擎切换成不支持事务的myisam,那事务就会失效了。

注意:

作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。

     作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。

     作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效

@Transactional详细介绍的更多相关文章

  1. [No0000A7]批处理经常用到的变量及批处理>NUL详细介绍

    绝对路径是指调用绝对的程序位置的路径,例如: start C:\Windows\test.exe 相对路径是文件改变路径以后还会按照变量的路径所在位置去调用,例如: start %WINDIR%\te ...

  2. linux配置网卡IP地址命令详细介绍及一些常用网络配置命令

    linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...

  3. _MSC_VER详细介绍

    _MSC_VER详细介绍 转自:http://www.cnblogs.com/braver/articles/2064817.html _MSC_VER是微软的预编译控制. _MSC_VER可以分解为 ...

  4. php CGI、Fastcgi、PHP-FPM的详细介绍与之间的关系

    以下PHP CGI.Fastcgi.PHP-FPM的一些信息归纳和汇总----->详细介绍与之间的关系 一:CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的 web ...

  5. RabbitMQ消息队列(一): Detailed Introduction 详细介绍

     http://blog.csdn.net/anzhsoft/article/details/19563091 RabbitMQ消息队列(一): Detailed Introduction 详细介绍 ...

  6. doT.js详细介绍

    doT.js详细介绍   doT.js特点是快,小,无依赖其他插件. 官网:http://olado.github.iodoT.js详细使用介绍 使用方法:{{= }} for interpolati ...

  7. Linux截屏工具scrot用法详细介绍

    Scrot是Linux命令行中使用的截图工具,能够进行全屏.选取等操作,下面小编将针对Scrot截图工具的用法给大家做个详细介绍,通过操作实例来学习Scrot的使用.   在Linux中安装Scrot ...

  8. Oracle Merge into 详细介绍

    Oracle Merge into 详细介绍 /*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查 ...

  9. cPage分页详细介绍

    asp.net中各种数据控件,datalist.gridview.Repeater等分页是最常用的功能,几乎任何一个B/S项目,无论是系统还是网站都会用到.分页时,读取整个数据,直接绑定到控件,都可以 ...

  10. 【转载】硬盘MBR详细介绍

    原文地址:http://blog.chinaunix.net/uid-15007890-id-106892.html 硬盘MBR详细介绍      硬盘是现在计算机上最常用的存储器之一.我们都知道,计 ...

随机推荐

  1. 无界面Linux系统和Windows系统使用selenium爬取CNVD数据

    因为CNVD官网采用了反爬机制,所以使用selenium能够更容易的爬取漏洞数据 1.在Windows中使用 注意根据chrome版本下载对应chromedriver 2.在无界面的Linux中使用 ...

  2. while循环内使用for循环

    一个基础问题,while循环内使用for循环,且当for循环内有控制while循环条件时. 如下所示: bool flag = true; while(flag) { for(i=0;i<10; ...

  3. 给含有关键词的label着色

    给含有关键词的label着色 FineFileType() { let arr = document.querySelectorAll('.el-checkbox__label'); for (let ...

  4. docker中搭建Ubuntu:16.04+python3.6+django环境

    用vim 新建一个Dockerfile和sources.list文件,在里面添加如下内容. #sources.list deb http://mirrors.163.com/ubuntu/ xenia ...

  5. OKHttp 之--------http/https协议处理方法 (Finn_ZengYuan博客)

    如果遇到okttp需要使用https协议,那么就需要在支持ssl,不说了,撸码搞起: 加入下面代码即可搞定:主要就是设置 builder.sslSocketFactory(sslParams.sSLS ...

  6. zuoye(借鉴)

  7. Github搜索优质项目方法

    [转载]:https://www.zhihu.com/question/20084458 搜索结果会显示非常多的开源项目,简直让你应接不暇,无从下手,很多小伙伴搜到这一步就放弃了,因为项目太多了,根本 ...

  8. json extionsion

    using System.Collections.Generic;using Newtonsoft.Json;using Newtonsoft.Json.Converters; namespace D ...

  9. 正确引用R及R包

    R版本不断更新,为保证数据可重复性,引用R时需标注出对应的R版本.那么如何引用呢? 打开R,键入citation(),得到对应的版本引用信息. To cite R in publications us ...

  10. [AGC013B] Hamiltonish Path

    个人思路: 随便从一个节点开始搜索,只要当前节点不满足条件,随便找一个与它有边相连,不在序列里的节点加入序列.因为要么中途停止,要么把所有节点遍历一遍,一定能找到一个端点. 我们直接从节点 \(1\) ...