spring中Transactional事务及事务参数配置

@Transactional注解方式:

   @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)

@Transactional属性

属性名

类型

说明

Isolation

枚举类型

事务隔离级别

noRollbackFor

Class<? Extends Throwable>[]

一组异常类,遇到时不回滚,默认为{}

noRollbackForClassName

String[]

一组异常类,遇到时不回滚,默认为{}

Propagation

枚举类型

事务传播行为

readOnly

Boolean

事务读写性

Rollback

Class<? Extends Throwable>[]

一组异常类,遇到时回滚

rollbackForClassName

String[]

一组异常类,遇到时回滚

Timeout

Int

超时时间,以秒为单位

Value

String

可选的限定描述符,制定使用的事务管理器

Value

value属性用于指定不同的事务管理器,主要用于满足同一个系统中,存在不同的事务管理器。如spring中可声明两种事务管理器txManager1,txManager2,用户则通过这个参数指定事务管理器。

Propagation

@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没有声明事务,那就不用事务

@Transactional(propagation=Propagation.NESTED)

若一个活动的事务存在,则运行在一个嵌套的事务中;

若没有活动事务,则按REQUIRED属性执行

REQUIRED_NEW和NESTED两种传播机制的区别:

REQUIRED_NEW:内部的事务独立运行,在各自的作用域中,可独立的回滚或提交,而外部的事务将不受内部事务的回滚状态影响。

NESTED:基于单一的事务来管理,提供了多个保存点,这种多个保存点的机制允许内部事务的变更出发外部事务的回滚,而外部事

务在回滚之后,仍能继续进行事务处理,即使部分操作已经回滚。

这两种传播机制都是事务嵌套,不同之处在于,内外事务之间是否存在彼此之间的影响;NESTED之间会收到影响,而产生部分回滚,,而

REQUIRED_NEW则是独立的。

isolation(隔离级别,多使用与多用户并发操作数据库,注意会引发的并发问题)

@Transactional(isolation=Isolation.READ_UNCOMMITTED)

读取未提交的数据,会出现脏读,不可重复读,基本不使用

@Transactional(isolation=Isolation.READ_COMMITTED)

读取已提交数据,会出现不可重复读和幻读,SQL server默认

@Transactional(isolation=Isolation.REPEATABLE_READ)

可重复读,会出现幻读

@Transactional(isolation=Isolation.SERIALIZABLE)

串行化

@Transactional(isolation=Isolation.DETAULT)

使用各个数据库默认的隔离级别

脏读(Dirty Read:一个事务更新了数据库中某些事务,另一个事务读取了这些数据,但这时前一个事务由于某些原型回滚了,那么第二个事务读取的数据就是“脏数据”。

不可重复读(Non-Repeatable read:一个事务需要两次查询同一数据,但两次查询中间可能有另外一个事务更改了这个数据,导致前一个事务两次读出的数据不一致。

幻读(Phantom Read:一个事务两次查询同一个表,但两次查询中间可能有另外一个事务又向这个表中插入了一些心数据,

导致一个事务两次的查询不一致。具体如何来设置具体的隔离级别,则依据业务系统具体可以容忍的程度而定。其中Serializable最为严格,然而效率最低;Read_Uncommited

效率最高,但是容易出现各种问题,中间的两个级别介于两者之间,故本质上是效率和出错概率的平衡和妥协。

Timeout

用于设置事务处理的时间长度,阻止可能出现的长时间的阻塞系统或占用系统资源。单位为秒。如果超时设置事务回滚,并抛出TransactionTimeOutException异常。

Spring事务超时 = 事务开始时到最后一个Statement创建时时间+最后一个Statement的执行时超时时间(即其queryTimeOut)

ReadOnly

默认情况下是false,可显式制定为true,表明该方法下使用的是只读操作,如果进行其他非读操作,则会抛出异常,这个仅仅试用于

只有readOnly标识的情况下,当其于propagation机制同时试用时,则会出现只读设置被覆盖的情况。

rollbackForClassName/rollbackFor

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚,这个例外时unchecked,如果遇到checked意外就不回滚。

用于指明回滚的条件是那些异常类或者异常类名。

noRollbackForClassName/noRollbackFor

作用同上,用来指明在抛出特定异常的情况下,不进行数据库的事务回滚操作。

 Spring事务回滚规则

      指定spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常,spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。

       默认配置下,spring只有在抛出的异常未运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Error也会导致事务回滚),而抛出的check异常则不会导致事务回滚。

      可以明确的配置在抛出哪些异常时回滚事务,包括checked异常。也可以明确定义哪些异常抛出时不回滚事务,也可通过setRollbackOnly()方法来指定一个事务必须回滚,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。

使用@Transactional的注意事项

  1. @Transactional注解应该只被应用到public可见度的方法上。如果在protected、private或package-visible的方法上使用@Transactional注解,它不会报错,但是这个被注解的方法不会展示已配置的事务设置。
  2. 用spring事务管理器,由spring来负责数据库的打开、提交、回滚。默认晕倒运行期异常会回滚,即遇到不受检查的异常的回滚;而遇到需要捕获的异常不会回滚,即遇到受检查的异常,需要我们指定方式让事务回滚,若想回滚所有异常,则家上@Transaction(rollbackFor={Exception.class})
  3. @Transactional注解可以被应用于接口定义和接口方法、类定义和类的public方法上。然而,仅仅@Transactional注解的出现不足于开启事务行为,它仅仅是一种元数据,能够被可以识别@Transactional注解和上述的配置具体事务行为的beans所使用。其实可以在<tx:annotation-driver />元素的出现可以开启事务行为。
  4. Spring团队的建议是在具体的类(或类的方法)上使用@Transaction注解,而不要使用在类索要实现的任何接口上。如果在接口上使用@Transactional注解,着注解只能在你设置了基于接口的代理时它才能生效,因为注解时不能继承了,这就意味着如果你证字啊使用基于类的代理时,那么事务的设置将不能被基于类等额代理锁识别,而且对象也将不会被事务代理所包装。
  5. @Transactional注解标识的方法,处理过程尽量的简单,尤其时带锁的事务方法,能不放在事务里面最好不要放在事务里面,可以将常规的数据库查询操作放在事务前面进行,而事务内进行增、删、改、加锁查询等操作。
  6. @Transactional的事务开启,或者是基于接口的或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值