Spring事务:保障钱不会丢

在MySQL中简单的了解过事务,简单说事务就是把一组操作封装成一个执行单元,要么全部成功,要么全部失败。

在一次转账中,第一步A减去一百元,第二步B增加一百元。如果没有事务,第一步执行成功了,但是第二步失败了,那么A的一百元就会平白无故的丢失。使用事务就可以解决这个问题,让这一组操作要么一起成功,要么一起失败。

编程式事务

编程式事务也就是手动写代码操作事务,有三个重要的步骤:

  1. 开启事务(获取事务)
  2. 提交事务
  3. 回滚事务

SpringBoot内置了两个对象,DataSourceTransactionManager用来获取事务、提交或回滚事务。而TransactionDefinition是事务的属性,在获取事务的时候需要将TransactionDefinition传递进去从而获得一个事务TransactionStatus。

Spring事务:保障钱不会丢_第1张图片

我们需要借助事务管理器来开启事务。并且提交事务和回滚事务通过commit和rollback来完成。

声明式事务

编程式事务虽然可以实现事务,但是操作也很繁琐,可以使用声明式事务来完成。

使用@Transactional注解就可以实现,无需手动开启事务和提交事务,进入方法时自动开启事务,方法执行完会自动提交事务,如果中途发生了没有处理的异常会自动回滚事务。

Spring事务:保障钱不会丢_第2张图片

@Transactional

  • 修饰方法:只能应用到public方法上,否则不生效
  • 修饰类:表名对这个类中所有的public方法都生效

Spring事务:保障钱不会丢_第3张图片

如果@Transactional在异常被捕获的情况下,是不会进行事务的自动回滚:

Spring事务:保障钱不会丢_第4张图片

此时有两种解决方案:

1.重新将异常抛出去:

Spring事务:保障钱不会丢_第5张图片

2.手动回滚事务

手动回滚事务,在方法中使用 TransactionAspectSupport.currentTransactionStatus() 可以得到当前的事务,然后设置回滚方法 setRollbackOnly 就可以实现回滚了。

Spring事务:保障钱不会丢_第6张图片

@Transactional工作原理

事务隔离级别

事务有四大特性(AICD),原子性、持久性、一致性和隔离性。而这四种特性中,只有隔离性(隔离级别)是可以设置的。设置事务的隔离级别可以用来保障多个并发事务执行更可控、更符合操作者的预期。

Spring事务:保障钱不会丢_第7张图片

MySQL 事务隔离级别有 4 种:

  • READ UNCOMMITTED:读未提交,也叫未提交读,脏读。
  • READ COMMITTED:读已提交,也叫提交读,不可重复读。
  • REPEATABLE READ::可重复读,是 MySQL 的默认事务隔离级别,幻读。
  • SERIALIZABLE:序列化,事务最⾼隔离级别,不会出现冲突问题。

在SQL中通过select @@global.tx_isolation,@@tx_isolation;来查询全局事务隔离级别和当前连接的事务隔离级别:

Spring事务:保障钱不会丢_第8张图片

Spring事务隔离级别有5种:

  • Isolation.DEFAULT:以连接的数据库的事务隔离级别为主。
  • Isolation.READ_UNCOMMITTED:读未提交,可以读取到未提交的事务,存在脏读。
  • Isolation.READ_COMMITTED:读已提交,只能读取到已经提交的事务,解决了脏读,存在不可重复读。
  • Isolation.REPEATABLE_READ:可重复读,解决了不可重复读,但存在幻读(MySQL默认级别)。
  • Isolation.SERIALIZABLE:串行化,可以解决所有并发问题,但性能太低。

事务传播机制

事务隔离级别解决的是同时调用一个数据库的问题,而事务传播机制解决的是多个事物同时调用数据库的问题。

Spring事务:保障钱不会丢_第9张图片

http://t.csdnimg.cn/myv2qicon-default.png?t=N7T8http://t.csdnimg.cn/myv2q

你可能感兴趣的:(spring,java,后端)