一、事务
多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功。
二、必须遵循的四个特性(原则:ACID)
- 原子性(Atomicity):事务是不可拆分的最小工作单元,事务内的操作,要么全做,要么全不做。
- 一致性(Consistency):事务执行前,数据库的数据处于正确状态;执行完后,数据库的数据还应该处理正确状态。例如:A转账给B,A转给B的钱,B一定要收到;不能出现:A的钱已经扣了,但是B并没有收到钱这种情况。
- 隔离性(Isolation):并发执行的事务之间,不互相影响。需要事务隔离级别指定隔离性。
- 持久性(Durability):事务执行完后,对数据库中数据的改变是永久性的。
三、事务分类
1、本地事务和分布式事务(按数据库分)
- 本地事务:独立在一个数据库的事务,保证在该数据库的ACID。
- 分布式事务:涉及两个或多个数据库源的事务,即跨越多台同类或异类数据库的事务(由每台数据库的本地事务组成),分布式事务旨在保证些本地事务的ACID,使事务可以跨越多台数据库。
2、JDBC事务和JTA事务(Java事务类型)
- JDBC事务:上面所说数据库事务中的本地事务,通过connection对象控制管理。
- JTA事务:Java事务API(Java Transaction API),是Java EE数据库事务规范,JTA只提供事务管理接口,由应用服务器厂商提供实现,JTA事务比JDBC更加强大,支持分布式事务。
3、声明式事务和编程式事务
- 声明式事务:通过xml配置或注解实现。
- 编程式事务:通过编程代码在业务逻辑时自行实现,粒度更小。
四、事务中的脏数据、脏读、不可重复读、幻读
1、脏读、脏数据
当一个事务正在访问数据,并对数据进行了修改,而这次修改还没有提交到数据库中。此时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外这个事务读取到的就是脏数据,依据脏数据做的操作可能是不正确的。
2、不可重复读
指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间,如果第二个事务对该数据进行了修改,就会导致两次读到的数据是不一样的。因此称为不可重复读。
3、幻读
事务不是独立执行时发生的现象。例如,第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这次修改是向表中插入一行新数据。那么就会发生操作第一个事务的用户发现表中还有没修改的数据行,就好象发生了幻觉一样。
五、Spring事务五大隔离级别
1、ISOLATION_DEFAULT
底层数据库的默认隔离级别,数据库管理员设置什么就是什么。
2、ISOLATION_READ_UNCOMMITTED(未提交读)
最低隔离级别,事务未提交前,就可以被其他事务读取(可能出现幻读、脏读、不可重复读)
3、ISOLATION_READ_COMMITTED(提交读)
一个事务提交后才能被其他事务读取到(该隔离级别禁止其他事务读取到未提交事务的数据,所以还是会造成幻读、不可重复读)。SQL Server的默认级别
4、ISOLATION_REPEATABLE_READ(可重复读)
保证多次读取到同一数据时,其值都和事务开始时的事务是一致的,禁止读取到别的事务未提交的数据(该隔离基本可防止脏读,不可重复读,但会出现幻读)。MySQL默认级别)
5、ISOLATION_SERIALIZABLE(序列化)
代价最高的隔离级别(可防止脏读、不可重复读、幻读)
六、Spring事务七大传播行为
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类似的操作