一、事务的起源
原子性(Atomicity):要么全做,要么全不做。
一致性(Consistency):数据库中的数据全部符合现实中的约束。
隔离型(Isolation):操作以原子性执行,且不同事务操作互不干扰。(多种隔离级别)
持久性(Durability):操作完成后,结果永久保留。
二、事务的概念
1、概念:把需要保证原子性、一致性、隔离性和持久性的一个或多个数据库操作称之为一个事务(英文名是: transaction )。
2、事务状态转换
三、事务的语法
1、开启事务
(1)begin;
(2)start transaction;
start transaction修饰符:
(1)read only;
(2)read write;
(3)with consistent snapshot;
默认:read write;
2、提交事务
(1)commit;
3、终止事务
(1)rollback;
4、支持事务的存储引擎
(1)支持:InnDB、NDB;
(2)不支持:MyISAM;
5、自动提交
(1)系统变量auticommit;
6、隐式提交
(1)概念:某些特殊的语句会导致事务提交,类似commit。
(2)数据定义语言DDL,如create、alter、drop等;
(3)隐式使用或修改MySQL数据库中的表;
(4)事务控制或关于锁定的语句;或者lock tables、unlocks tables;
(5)加载数据的语句,如load data;
(6)关于MySQL复制的一些语句及其他;
四、拓展应用
以下情况事务不生效
1、未启用spring事务管理功能
@EnableTransactionManagement 注解用来启用spring事务自动管理事务的功能。
2、方法不是public类型的
@Transactional可以用在类上、接口上、public方法上,如果将@Transactional用在了非public方法上,事务将无效。
3、数据源未配置事务管理器
spring是通过事务管理器了来管理事务的,需要为每个数据源配置一个事务管理器。
4、调用问题
spring是通过aop的方式,对需要spring管理事务的bean生成了代理对象,然后通过代理对象拦截了目标方法的执行,在方法前后添加了事务的功能,所以必须通过代理对象调用目标方法的时候,事务才会起效。
解决办法:
(1)AopContext.currentProxy();
(2)在类中注入自己;
5、异常类型错误
@Transactional默认只回滚RuntimeException和Error。
解决办法:
指定@Transactional(rollbackFor = Exception.class)的方式进行全异常捕获。
6、异常被吞
spring感知到异常的时候,才会做事务回滚的操作,若方法内部将异常给吞了,那么事务无法感知到异常。
7、多线程
Spring事务通过ThreadLocal保存事务信息,事务与线程绑定,多线程下不受控制。
参考资料
【1】《MySQL是怎样运行的》
【2】MySQL官方文档
【3】Spring 事务失效的7种场景