Spring事务

事务,是在数据库中用于保证数据正确性的一种机制,涉及到很多概念以及不同的情况,这里做一个总结

相关概念

事务四特性(ACID)

原子性(Atomicity,或称不可分割性):要么全部完成或者全部不完成,错误是会发生回滚,这个要求两条相关的操作,就像情侣一样,要么一起海誓山盟,一个发生意外,另外一个也挂了

一致性(Consistency):操作完成后和原本想的结果一样,不能对数据完整性造成破坏

隔离性(Isolation,又称独立性):可以同时开启多个事务,为避免出现错误,针对这个问题制定了事务在处理时对数据进行不同隔离

持久性(Durability):事务操作后数据永久存储数据库。

事务并发问题

脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据,数据是错误的就是脏数据

不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

幻读:一个事务进行数据处理,正在处理时插入一条记录,原本事务处理后发现一条记录没有更改,如同发生幻觉一般。

spring事务机制

spring针对事务进行一系列的处理

事务隔离级别

在多个事务进行处理的时候锁住数据,保证统一时间只有一个事务对数据进行处理,针对不同的情况有不同的锁

DEFAULT(默认值):使用底层数据库事务隔离级别,MySql中使用select @@tx_isolation可以查询当前隔离级别

READ_COMMITTED:读已提交,读到已经提交的数据,可以防止脏读,但是对不可重复读和幻读

READ_UNCOMMITTED:读未提交,可以读取没有提交的数据,较少用

REPEATABLE_READ:重复读取,读出去后自动加锁,其他事务不能修改,解决脏读,不可重复读

SERIALIZABLE:串行化,事务一个排一个执行,一个事务执行完成后执行下一个

事务传播机制

在服务中进行数据库操作,两个操作中事务如何管理

REQUIRED(默认值):如果当前没有事务开启一个事务,有的话自动加入到这个事务中

REQUIRES_NEW :针对被调用者,不管调用者是否存在事务,被调用者创建一个新事务。

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

NESTED:如果存在事务,嵌套事务中执行,如果没有则新建

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

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

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

事物注解方式: @Transactional

当标于类前时, 标示类中所有方法都进行事物处理 , 例子:

1 @Transactional 
public class TestServiceBean implements TestService {}

当类中某些方法不需要事物时:

@Transactional
public class TestServiceBean implements TestService {
    private TestDao dao;
    public void setDao(TestDao dao) {
        this.dao = dao;
    }
    @Transactional(propagation =Propagation.NOT_SUPPORTED)
    public List getAll() {
        return null;
    }
}

@Transactional注解中常用参数说明

readOnly:
该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

rollbackFor
该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:

指定单一异常类:
@Transactional(rollbackFor=RuntimeException.class)
指定多个异常类:
@Transactional(rollbackFor={RuntimeException.class, Exception.class})

rollbackForClassName

该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:

指定单一异常类名称:
@Transactional(rollbackForClassName="RuntimeException")
指定多个异常类名称:
@Transactional(rollbackForClassName={"RuntimeException","Exception"})

noRollbackFor

该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:

指定单一异常类:
@Transactional(noRollbackFor=RuntimeException.class)
指定多个异常类:
@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:

指定单一异常类名称:
@Transactional(noRollbackForClassName="RuntimeException")
指定多个异常类名称:
@Transactional(noRollbackForClassName={"RuntimeException","Exception"})

propagation

该属性用于设置事务的传播行为。

@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

isolation

该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置

timeout

该属性用于设置事务的超时秒数,默认值为-1表示永不超时

Spring事务在哪些情况下失效

1.数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的
2.@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
3.Service类没有被Spring管理。因为Spring的事务是基于AOP,所以如果Service类没有被Spring管理,变成一个Spring Bean,即使添加了@Transactional注解,事务也是无效的。
4.是不是同一个类中的方法调用
5.异常是不是被catch住了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值