Spring事物原理详解

spring的4种事务特性,5种隔离级别,7种传播行为

什么是事务?

事务(Transaction) 是访问并可能更新数据库中各种数据项的一个程序执行单元。
事务是恢复和并发控制的基本单元,有以下4个属性(ACID):

  1. 原子性:一个事务是一个不可分割的工作单位,事务中包括的诸多操作要么都做,要么都不做;
  2. 一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。事务的一致性和原子性是密切相关的。
  3. 隔离性:一个事务的执行不能被其他事务干扰。
  4. 持久性:持久性也称为永久性,指一个事务一旦提交,它的改变就是永久性的。

Spring事物的本质其实就是数据库对事物的支持,没有数据库的事物支持,spring是无法提供事务功能的,对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤:

  1. 获取连接 Connection con = DriverManager.getConnection();
  2. 开启事务 con.setAutoCommit(true/false);
  3. 执行crud操作;
  4. 提交事务/回滚事务 con.commit() / con.rollback();
  5. 关闭连接 con.close();

使用spring的事物管理功能之后,我们可以不用再写步骤2和4的代码,而是有spring自动完成。下面以注解方式为例:

  1. 配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional标识;
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory"  ref="entityManagerFactory"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

	@TargetDataSource(dataSource = TargetDataSource.DataSourceEnum.write)
    @Transactional(rollbackFor = Exception.class)
    public void updateRoleFunctionByRoleId(MaintenanceUser maintenanceUser, Long roleId, String allowFuncs) {
        // 业务逻辑代码
    }
  1. spring在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transactional的相关参数进行相关的配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务);
  2. 真正的数据库层的事务提交和回滚是通过bin log或者redo log实现的。

Spring事务的传播属性:

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。这些属性在TransactionDefinition中定义:Spring事务传播属性和隔离级别

spring事务有7种传播行为,分别是:

1、PROPAGATION.REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

2、PROPAGATION.SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

3、PROPAGATION.MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

4、PROPAGATION.REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

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

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

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

注解@Transactional默认的传播行为是:PROPAGATION.REQUIRED
在这里插入图片描述

注意事项:

1、在需要事务管理的地方加@Transactional 注解。@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。

2、@Transactional 注解只能应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。

3、注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据。必须在配置文件中使用配置元素,才真正开启了事务行为。

4、Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。

数据库隔离级别 : 事务的四种隔离级别

在这里插入图片描述
临时表:针对每张表一一对应的表,单例的,只要一张表;判断这条数据有没有被锁定,有没有正在被操作,只要看看临时表里面有没有这条记录。数据被修改了,没有被提交,只是存在于临时表中,处于临时状态。有可能会被撤回,被回滚。当用户去查询表时,临时表里面有这条数据,数据会被优先访问。如果前一个事务发生回滚,则会导致用户读取的数据和我们数据库持久化的数据是不一致的,这种情况就叫脏读。临时表在事务commit()或者rollback()以后就会消失。

  1. 脏读:一个事务对数据进行了增删改,但是还未提交(数据在我们的临时表里面);另一个事务可以读取到未提交的数据(读取临时表中的数据),如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。
  2. 不可重复读:一个事务中发生了2次读操作,第一次读操作(临时表)和第二次读操作之间,另一个事务对数据进行了修改(临时表),这时候2次读取的数据是不一致的。
  3. 幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这个时候第一个事务就会丢失对新增数据的修改。

总结:
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大;
大多数的数据库默认隔离级别为Read Commited,比如SqlServer,Oracle;
少数数据库默认隔离级别为:Repeatable Read ,比如:MySQL

Spring事务接口管理

在这里插入图片描述

总结:

  1. 什么是事物?
    一个整体的执行逻辑单元,只有两个结果,要么全失败,要么全成功。

  2. 事务的特性
    原子性,隔离性,持久性,一致性。

  3. 事务的基本原理
    从数据库角度来说:就是提供了一种后悔机制。这里用到了临时表,在执行增删改之前,先将满足条件的数据查询出来放入到临时表中,然后先在临时表中操作这些数据,完成过程中如果没有出现任何问题,就将临时表中的数据同步到实际的表中,并返回影响的行数。
    如果在临时表中操作数据时出现了错误,那就将临时表中满足条件的数据清除,并返回错误码。
    如果想要对一个数据表的数据进行清空,千万别用delete from ,这种情况会锁表;加了where条件就是行锁。

  4. spring的事务配置
    AOP配置:指定需要加事务的方法;
    声明试事务配置,事务的传播属性,隔离级别,回滚条件等;
    传播属性:DEFAULT REQUIRED EQUIRES_NEW SUPPORTS NESTED
    隔离级别:DEFAULT READ_UNCOMMITTED READ_COMMITTED REPEATABLE_READ SERIALIZABLE

  5. 源码分析
    通过解析配置文件,得到TransactionDefintion 实际上就是AOP中的MethodInterceptor(方法代理),然后可以在满足条件的方法调用前后加一些东西;

    PlatformTransactionManager 中的方法:
    getTransaction 调用了TransactionSynchronizationManager类的getResource();从ThreadLocal里面取值, Map<DataSource,CommectionHolder> 获取一个连接对象Connection;

    conn.setAutoCommit(false);
    Commit con.commit();
    Rollback con.rollback();

参考链接:spring事务原理spring编程式事务和声明式事务spring编程式事务

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值