事务是保持数据一致性的,事务包含一个或多个业务操作,这些操作要么都执行,要么都不执行。事务常被用来确保数据的一致性。
-
事务四大特性:原子性
原子性是指事物所包含的操作要么全部执行,要么全不执行。所有失败的操作都必须回滚。 -
一致性
一致性是说事物从一个一致性结果变化为另一个一致性结果的状态,也就是一个事务执行之前和执行之后都必须处于一致性状态。 -
隔离性
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。 -
持久性
持续性
指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
spring boot是默认启动事务的,只需要在类或者方法上添加@Transactional注解即可,但有时候会发现事务不生效,具体原因可以从以下几个方面找寻:
1、首先要看数据库引擎是否支持注解,mysql默认引擎INNODB是支持的,但MYISAM是不支持的;
2、注解只能被应用到public方法上, 其它方法上不会报错,但不生效;
3、默认情况下只会对运行期异常(java.lang.RuntimeException及其子类)和 Error 进行回滚;
4、如果是其它异常,可以显形标记在参数里,下图标红的就是先进行查看用户有指定的异常,如果没有,就默认上一条的异常,参数格式:@Transactional(rollbackFor={Exception.class})
5、是否进行了异常捕获,如果使用了try–catch,事务是肯定不生效,也就是系统没有接收到异常场景;
关于使用异常捕获,还想事务生效,可以有几种策略解决相关难题:
1)手动回滚,推荐方式
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
2)在catch里抛出一个runntimeException
- 将异常写入注解参数里面,也需要抛出来,原理跟方法2一样的,只是重新指定了事务回滚的异常类型
扩展----隔离级别
Spring 传播七种行为
Propagation
- PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常