数据库------事务
-
- [一、 **什么是事务**:](#一、 什么是事务:)
- 二、事务的特点:
- 三、一个例子说明事物
- 四、事务的隔离性
-
- [4.1 五种并发异常](#4.1 五种并发异常)
-
- [4.1.1 第一类丢失更新](#4.1.1 第一类丢失更新)
- [4.1.2 第二类丢失更新](#4.1.2 第二类丢失更新)
- [4.1.3 脏读](#4.1.3 脏读)
- [4.1.4 不可重复读](#4.1.4 不可重复读)
- [4.1.5 幻读](#4.1.5 幻读)
- [4.2 使用四种隔离级别去处理这五种并发异常](#4.2 使用四种隔离级别去处理这五种并发异常)
- [4.3 事务管理的实现机制](#4.3 事务管理的实现机制)
-
- [4.3.1 悲观锁(数据库自带的)](#4.3.1 悲观锁(数据库自带的))
- [4.3.2 乐观锁(自定义实现)](#4.3.2 乐观锁(自定义实现))
- [4.4 Spring事务管理](#4.4 Spring事务管理)
一、 什么是事务:
事务是在数据库中执行的一系列操作单元,这些操作要么全部成功提交,要么全部失败回滚。
二、事务的特点:
- 原子性 (Atomicity):事务是一个不可分割的操作单元,要么全部执行成功,要么全部执行失败。如果事务中的任何一部分操作失败,将回滚到事务开始前的状态,保证数据的完整性。
- 一致性 (Consistency):事务执行的结果,须使数据从一个一致性状态到另一个一致性状态;
- 隔离性 (Isolation):事务的执行互不干扰,任何事务内部操作对其他事务都是隔离的。并发执行的多个事务之间应该互相隔离,以防止数据争用和不一致的问题。
- 持久性 (Durability):一旦事务提交成功,它对数据库的改变应永久保存,即使系统发生故障也不会丢失。数据库系统通过将事务的操作记录写入持久存储介质(如磁盘)来保证数据的持久性。
三、一个例子说明事物
假设有一个银行系统,其中有两个账户:账户A和账户B。现在有一个转账操作需要将一定金额从账户A转移到账户B。
在这个转账操作中,可以将其作为一个事务来处理。事务包含以下步骤:
- 开始事务。
- 从账户A扣除一定金额。
- 向账户B添加同样的金额。
- 提交事务。
如果在整个过程中没有出现错误,即成功执行了步骤 2 和步骤 3,并且事务成功提交,那么账户A和账户B的余额将会根据转账操作进行更新,保持总额不变。
然而,如果在执行过程中出现了错误,比如步骤 3 遇到了问题,无法向账户B添加金额,那么事务将会回滚(Rollback),取消之前的步骤,账户A的金额也不会被扣除。
四、事务的隔离性
- 五种常见的并发异常
- 第一类丢失更新、第二类丢失更新
- 脏读、不可重复读、幻读
- 常见的隔离级别
- Read Uncommitted: 读取未提交的数据
- Read Committed: 读取已提交的数据
- Repeatable Read: 可重复读
- Serializable: 串行化
4.1 五种并发异常
4.1.1 第一类丢失更新
某一个事务的回滚,导致另一个事务已更新的数据丢失。
4.1.2 第二类丢失更新
某一个事务的提交 ,导致另一个事务已更新的数据丢失。
4.1.3 脏读
某一个事务,读取了另外一个事务未提交的数据。
4.1.4 不可重复读
一个事务对同一个数据前后读取结果不一致。
时间 | 事务A | 事物B |
---|---|---|
T1 | 开始事务 | |
T2 | 开始事务 | |
T3 | 查询账户余额为1000 | |
T4 | 取款1000,存款余额为0 | |
T5 | 查询账户余额为0 |
4.1.5 幻读
某一个事务,对同一个表前后查询到的行数不一致。
时间 | 事务A | 事物B |
---|---|---|
T1 | 开始事务 | |
T2 | 开始事务 | |
T3 | 查询账户余额小于10的用户(10人) | |
T4 | 新增一账户且余额小于10 | |
T5 | 查询账户余额小于10的用户(11人) |
4.2 使用四种隔离级别去处理这五种并发异常
隔离级别 | 第一类丢失更新 | 脏读 | 第二类丢失更新 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
读未提交的数据 | Y | Y | Y | Y | Y |
读已提交的数据 | -- | -- | Y | Y | Y |
可重复读 | -- | -- | -- | -- | Y |
串行化 | -- | -- | -- | -- | -- |
- 数据安全性极高:串行化
- 性能高:读已提交的数据
4.3 事务管理的实现机制
4.3.1 悲观锁(数据库自带的)
看待问题悲观:只要并发就一定有问题
- 共享锁(S锁)
- 事务A对数据加了S锁后,其他事物只能加S锁,不能加X锁。即只能读、不能写。
- 排他锁(X锁)
- 事物A对数据加了X锁后,其他事物对该数据不能加S锁也不能加X锁。即不能读、不能写。
4.3.2 乐观锁(自定义实现)
乐观看待问题:即使并发了,也不会有问题
- 版本号、时间戳 等
- 在更新数据前,检查版本号是否发生变化。若变化则放弃本次更新,否则跟新数据(版本号+1)。
4.4 Spring事务管理
- 声明式事务(开发中常用)
- 通过XML配置,声明某方法的事务特征;
- 通过注解,声明某方法的事务特征。
- 编程式事务
- 通过Transaction Template管理事务,通过它执行数据库操作。
java
/* propagation为传播机制
A调B,对于B来说,A为当前事务(外部事物)
1. REQUIRED: 如果存在当前事务,那就加入该事务;如果不存在,就创建新事务;
2. REQUIRED_NEW:创建一个新事务,并且暂停当前事务;
3. NESTED:如果当前存在事务,则嵌套在该事物中执行(可独立地提交和回滚);否则和REQUIRED一样
*/