spring @Transactional 事务注解
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
简单解析:如果有事务,那么加入事务,没有的话新建一个; 串行化最高级隔离级别; 遇到异常回滚。
@Transactional之value
value这里主要用来指定不同的事务管理器;主要用来满足在同一个系统中,存在不同的事务管理器。比如在Spring中,声明了两种事务管理器txManager1, txManager2.
然后,用户可以根据这个参数来根据需要指定特定的txManager.
@Transactional之propagation(service中调用其他service时需要注意)
@Transactional(propagation=Propagation.REQUIRED) | 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下) |
@Transactional(propagation=Propagation.NOT_SUPPORTED) | 容器不为这个方法开启事务 |
@Transactional(propagation=Propagation.REQUIRES_NEW) | 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务 |
@Transactional(propagation=Propagation.MANDATORY) | 必须在一个已有的事务中执行,否则抛出异常 |
@Transactional(propagation=Propagation.NEVER) | 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反) |
@Transactional(propagation=Propagation.SUPPORTS) | 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务。如果其他bean没有声明事务,那就 |
Propagation支持7种不同的传播机制:
- REQUIRED
业务方法需要在一个事务中运行,如果方法运行时,已处在一个事务中,那么就加入该事务,否则自己创建一个新的事务.这是spring默认的传播行为.。
- SUPPORTS:
如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分,如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
- MANDATORY:
只能在一个已存在事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下调用,就抛异常
- REQUIRES_NEW
业务方法总是会为自己发起一个新的事务,如果方法已运行在一个事务中,则原有事务被挂起,新的事务被创建,直到方法结束,新事务才结束,原先的事务才会恢复执行.
- NOT_SUPPORTED
声明方法需要事务,如果方法没有关联到一个事务,容器不会为它开启事务.如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行.
- NEVER:
声明方法绝对不能在事务范围内执行,如果方法在某个事务范围内执行,容器就抛异常.只有没关联到事务,才正常执行.
- NESTED:
如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保证点.内部事务回滚不会对外部事务造成影响, 它只对DataSourceTransactionManager 事务管理器起效.
其实大家最感到困惑的是REQUIRED_NEW和NESTED两种不同的传播机制,功能类似,都涉及到了事务嵌套的问题,那两者有何区别呢?该如何正确使用这两种模式呢?
@Transactional(isolation = Isolation.READ_UNCOMMITTED) | 读取未提交数据(会出现脏读, 不可重复读) 基本不使用 |
@Transactional(isolation = Isolation.READ_COMMITTED)(SQLSERVER默认) | 读取已提交数据(会出现不可重复读和幻读) |
@Transactional(isolation = Isolation.REPEATABLE_READ) | 可重复读(会出现幻读) |
@Transactional(isolation = Isolation.SERIALIZABLE) | 串行化 |
隔离级别所要解决的问题是在应用程序中,存在多个事务同时在运行之时,需要解决和处理好的问题。那首先来看看,一般会出现哪些问题呢?先来看看吧。
- 脏读(dirty read)
一个事物更新了数据库中的某些数据,另一个事物读取了这些数据,这时前一个事物由于某些原因回滚了,那么第二个事物读取的数据就是“脏数据”
- 不可重复读(non-repeatable read)
一个事物需要两次查询同一数据,但两次查询中间可能有另外一个事物更改了这个数据,导致前一个事物两次读出的数据不一致。
- 幻读 (phantom read)
一个事物两次查询同一个表,但两次查询中间可能有另外一个事物又向这个表中插入了一些新数据,导致前一个事物的两次查询不一致
下面来看看Spring中@Transactional中Isolation有具备的值:
- DEFAULT 使用各个数据库默认的隔离级别
- Read Uncommited :读未提交数据( 会出现脏读,不可重复读,幻读 )
- Read Commited :读已提交的数据(会出现不可重复读,幻读)
- Repeatable Read :可重复读(会出现幻读)
- Serializable :串行化
@Transactional之timeout
用于设置事务处理的时间长度,阻止可能出现的长时间的阻塞系统或者占用系统资源。单位为秒。如果超时设置事务回滚,并抛出TransactionTimedOutException异常。
Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。
关于事务超时时间的计算可以参考:http://jinnianshilongnian.iteye.com/blog/1986023
@Transactional之readOnly
默认情况下是false,可以显示指定为true, 告诉程序该方法下使用的是只读操作,如果进行其他非读操作,则会跑出异常;这个紧紧适用于只有readOnly标识的情况下,当其与propagation机制同时使用之时,则会出现只读设置被覆盖的情况,比如在required的情况下。在使用 REQUIRED 传播模式时,会抛出一个只读连接异常。使用 JDBC 时是这样。使用基于 ORM 的框架时,只读标志只是对数据库的一个提示,并且一条基于 ORM 框架的指令(本例中是 hibernate)将对象缓存的 flush 模式设置为 NEVER,表示在这个工作单元中,该对象缓存不应与数据库同步。不过,REQUIRED 传播模式会覆盖所有这些内容,允许事务启动并工作,就好像没有设置只读标志一样。
具体的详细内容可以参考: http://robinsoncrusoe.iteye.com/blog/825531
@Transactional之rollbackForClassName/rollbackFor
Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked,如果遇到checked意外就不回滚。
用来指明回滚的条件是哪些异常类或者异常类名。用法比较简单,这些不再赘述。
@Transactional之noRollbackForClassName/noRollbackFor
作用雷同于8, 用来指明在抛出特定异常的情况下,不进行数据库的事务回滚操作。
- spring事务回滚规则
- @Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
- 用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚。默认遇到运行期异常(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的异常时回滚;而遇到需要捕获的异常(throw new Exception("注释");)不会回滚,即遇到受检查的异常(就是非运行时抛出的异常,编译器会检查到的异常叫受检查异常或说受检查异常)时,需我们指定方式来让事务回滚 要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception。class,其它异常}) 。
- @Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。上面的例子中,其实正是 <tx:annotation-driven/>元素的出现 开启了事务行为。
- Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装(将被确认为严重的)。因此,请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。
- @Transactional 注解标识的方法,处理过程尽量的简单。尤其是带锁的事务方法,能不放在事务里面的最好不要放在事务里面。可以将常规的数据库查询操作放在事务前面进行,而事务内进行增、删、改、加锁查询等操作。
- @Transactional 的事务开启 ,或者是基于接口的 或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。
spring @Transactional 事务注解的更多相关文章
- spring @Transactional 事务注解的坑
1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义和类的 public 方法上. 2. @Transactiona ...
- Spring提取@Transactional事务注解的源码解析
声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记: 难免有错误,敬请读者谅解!!! 1.事务注解标签 <tx:annotation-driven /> 2.tx 命名空间 ...
- Spring中的@Transactional事务注解
事务注解方式 @Transactional 当标于类前时, 标示类中所有方法都进行事物处理 , 例子: @Transactional public class TestServiceBean impl ...
- 《四 spring源码》spring的事务注解@Transactional 原理分析
先了解什么是注解 注解 Jdk1.5新增新技术,注解.很多框架为了简化代码,都会提供有些注解.可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件. 注解不会也不能影 ...
- @Transactional 事务注解
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...
- Spring @Transactional 事务机制
几个概念要清楚:事务的传播机制,事务的边界 工作原理 运行配置@Transactional注解的测试类的时候,具体会发生如下步骤 1)事务开始时,通过AOP机制,生成一个代理connection对象, ...
- Spring @Transactional ——事务回滚
工作原理运行配置@Transactional注解的测试类的时候,具体会发生如下步骤1)事务开始时,通过AOP机制,生成一个代理connection对象,并将其放入DataSource实例的某个与Dat ...
- spring @Transactional事务失效
不开事务几种情形 ① @Transactional写在了private方法上 org.springframework.transaction.interceptor.AbstractFallbackT ...
- spring mvc事务注解
@Transactional(noRollbackFor=RuntimeException.class)方法事务说明@Transactional(RollbackFor=Exception.class ...
随机推荐
- ConcurrentModificationException(并发修改异常)的分析
1)介绍 并发修改ConcurrentModificationException错误是开发中一个常见错误,多发生在对一个Collection边遍历边做影响size变化的操作中,下面以ArrayList ...
- crc循环冗余检验
CRC(Cyclic Redundancy Check):循环冗余检验.在链路层被广泛使用的检错技术. CRC原理: 1.发送端 1.1.在发送端先将数据分组,每组k个数据.假定要传送的数据是M. 1 ...
- LoadRunner之IP欺骗
一.启动IP欺骗,弹出提示窗口: 二.将本机改为静态IP: 1.查看当前的IP相关信息: 2.更改IP: 三.正式设置模拟IP号段: 1.重复步骤一,会弹出如下弹窗,选择第二项并下一步: ...
- day 51 js-2 函数,对象,正则 (定时器示例)
本文转载自cnblogs.liwenzhou-----哪吒博客 先来一个定时器让我们看看函数的效果: <script src="/js/jquery-3.2.1.min.js" ...
- 【java并发核心八】Fork-Join分治编程
jdk1.7中提供了Fork/Join并行执行任务框架,主要作用就是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总. 正常情况下,一些小任务我们可以使用单线程递归来实现,但是如果要想充分 ...
- SpringMVC(二四) 视图解析流程
目标方法无论返回的是string.ModelAndView.View,最终都被解析成modelAndView 关键的实现代码是在springmvc.xml配置文件中定义解析器. 参考代码如下: < ...
- SpringBoot使用Mybatis-Generator
本文介绍如何将Maven和Mybatis-Generator配合使用. 简介 Mybatis-Generator是Mybatis提供的一个便捷型插件,自动可以为项目生产对应的实体类,Mapper,da ...
- CSS选择器、样式、盒模型
一.CSS基础选择器 # 1.*(通配选择器):html,body以及body下用于显示的标签 #html和body颜色会被改变,但是div标签不会发生改变,由于不同的选择器具有优先级 # 语法:* ...
- codeforces651----A. Joysticks
//贪心,注意特判即可 #include <iostream> using namespace std; int main() { ; cin >> a >> b; ...
- python基础一 ------简单队列用作历史记录
#需求:测试历史记录,一个猜字游戏,能在重新进入游戏时查看输入历史# #-*-coding:utf-8-*- from random import randint from collections i ...