一、定义:
事务就是对数据库的一系列操作(如对数据库的增删改查),将这些操作看成一个整体,要么全部成功,要么全部失败。不存在部分成功,部分失败这种情况。
二、数据库事务的4个特性(ACID)
1、原子性(Atomic):表示组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回初始状态。(事务回滚)
2、一致性(Consistency):事务操作成功之后,数据库所处的状态和他的业务规则是一致的,即数据不会被破坏。如A转账50元到B账户,无论成功与否,A、B存款总额不变。
3、隔离性(Isolation):在并发数据操作时,不同的事务拥有各自的数据空间,他们的操作不会对对方产生干扰。准确地说,并非要求做到完全无干扰,数据库规定了很多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱。
4、持久性(Durability):一旦事务提交成功后,事务中对所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证能够通过某种机制恢复数据。(重执行日志)
三、事务属性
1、事务的传播行为(Propagation):一个事务调用另一个事务,以共同完成一个完整的业务操作。需要指定事务是如何进行传播的。
Spring中规定了7种:
事务传播行为类型 | 说明 |
---|---|
PROPAGATION_REQUIRED(默认传播行为) | 如果当前没有事务,就新建一个事务,如果已经存在一个事务,就加入到这个事务中。 |
PROPAGATION_REQUIRES_NEW | 表示当前方法必须在事务中执行,并新建当前方法的事务。如果调用的方法存在事务,就把当前事务挂起 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 |
PROPAGATION_MANDATORY | 使用当前事务,如果当前事务不存在,就抛出异常 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,就抛出异常 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行;如果不存在,则执行与PROPAGATION_REQUIRED类似的操作 |
2、数据并发产生的问题
(1)脏读(dirty read):A事务读取B事务尚未提交的更改的数据,并在这个数据的基础上进行操作。如果B事务回滚,那么A事务的读到的数据是无效的、不被承认的。
(2)不可重复读(unrepeatable read):A事务读取了进行两次或以上查询操作,B事务在A查询期间进行数据操作,导致每次读取到的数据不同。
(3)幻读(phantom read):A事务读取B事务提交的新增数据。一般发生在数据统计中。
3、事务隔离:隔离级别越高,数据库的并发性和吞吐量越低。