事务基础知识
文章目录
- 事务基础知识
- 1. 概述
- 2. 事务的ACID特性
- 3. 事务的状态
- 4. 事务的使用
- 4.1 显式事务
- 4.2 隐式事务
- 5. 事务隔离级别
- 5.1 数据并发问题
- 5.2 SQL中的四种隔离级别
1. 概述
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
事务处理的原则:保证所有事务都作为 一个工作单元
来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交( commit ),那么这些修改就 永久
地保存下来;要么数据库管理系统将 放弃
所作的所有 修改 ,整个事务回滚( rollback
)到最初状态。
2. 事务的ACID特性
-
原子性(atomicity):原子性是指事务是一个不可分割的工作单位,要么全部提交,要么全部失败回滚
-
一致性(consistency):根据定义,一致性是指事务执行前后,数据从一个
合法性状态
变换到另外一个合法性状态
。这种状态是语义上
的而不是语法上的,跟具体的业务有关。-
那什么是合法的数据状态呢?满足
预定的约束
的状态就叫做合法的状态。通俗一点,这状态是由你自己来定义的(比如满足现实世界中的约束)。满足这个状态,数据就是一致的,不满足这个状态,数据就是不一致的!如果事务中的某个操作失败了,系统就会自动撤销当前正在执行的事务,返回到事务操作之前的状态;比如A有
200元
转账出去300元
。就能发现数据不一致了,因为余额变成了-100元
,而对于余额的状态应该要满足余额>=0
的
-
-
隔离性(isolation):事务的隔离性是指一个事务的执行
不能被其他事务干扰
,即一个事务内部的操作及使用的数据对并发
的其他事务是隔离的,并发执行的各个事务之间不能互相干扰 -
持久性(durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是
永久性
的 ,接下来的其他操作和数据库故障不应该对其有任何影响
总结
ACID 是事务的四大特性,在这四个特性中,原子性是基础,隔离性是手段,一致性是约束条件,而持久性是我们的目的。
数据库事务,其实就是数据库设计者为了方便起见,把需要保证
原子性
、隔离性
、一致性
和持久性
的一个或多个数据库操作称为一个事务。
3. 事务的状态
- 活动的(active):事务对应的数据库操作正在执行过程中
- 部分提交的(partially committed):操作都在内存中执行,所造成的影响并
没有刷新到磁盘
时 - 失败的(failed):遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为的停止当前事务的执行
- 中止的(aborted):当
回滚
操作执行完毕时,也就是数据库恢复到了执行事务之前的状态 - 提交的(committed):在
部分提交的
状态将数据同步到磁盘
上之后的状态
一个基本的状态转换图如下所示:
图中可见,只有当事务处于 提交的
或者 中止的
状态时,一个事务的生命周期才算是结束了。对于已经提交的事务来说,该事务对数据库所做的修改将永久生效,对于处于中止状态的事务,该事务对数据库所做的所有修改都会被回滚到没执行该事务之前的状态。
4. 事务的使用
使用事务有两种方式,分别为 显式事务
和 隐式事务
4.1 显式事务
步骤1:开启事务
mysql> BEGIN;
#或者
mysql> START TRANSACTION;
START TRANSACTION
语句相较于 BEGIN 特别之处在于,后边能跟随几个 修饰符
:
READ ONLY
:标识当前事务是一个只读事务
READ WRITE
:标识当前事务是一个读写事务
WITH CONSISTENT SNAPSHOT
:启动一致性读- 事务一般不是在执行
BEGIN
或START TRANSACTION
就开启的,而是在执行事务开启语句后的第一个SQL执行前开启的,使用WITH CONSISTENT SNAPSHOT
参数即可使得事务在BEGIN
或START TRANSACTION
执行时便开启,这便是该参数事务开启便带一致性快照的含义
- 事务一般不是在执行
步骤2:一系列事务中的操作(主要是DML,不含DDL)
步骤3:提交事务 或 中止事务(即回滚事务)
# 提交事务。当提交事务后,对数据库的修改是永久性的。
mysql> COMMIT;
# 回滚事务。即撤销正在进行的所有没有提交的修改
mysql> ROLLBACK;
# 将事务回滚到某个保存点,回滚保存点后事务还没到终止状态,还能继续提交或回滚。SAVEPOINT s1; 设置保存点;
mysql> ROLLBACK TO [SAVEPOINT] -- SAVEPOINT s1; 设置保存点;
4.2 隐式事务
MySQL中有一个系统变量 autocommit
:默认开启;可设置为关闭,或者显式开启事务即可关闭掉自动提交事务的功能
set autocommit = false; -- true | false
MySQL在执行其他非DML语句时大部分会隐式提交当前事务,已经显式开启事务还没提交便再次开启事务会先隐式提交上个事务,再开启一个新的事务。
5. 事务隔离级别
5.1 数据并发问题
访问相同数据的事务在 不保证串行执行
的情况下可能会出现哪些问题:
- 脏写( Dirty Write ):A 修改了 B 修改过但还未提交的数据
- 脏读( Dirty Read ): A 读取了 B 修改过但还未提交的数据
- 不可重复读( Non-Repeatable Read ):A 读取了一个字段,B 更新了这个字段,A 再次读取该字段,值不相同了
- 幻读( Phantom ):A 读取了某个表的数据,B 插入了一些新的行,A再次读取该表数据,数据相比之前多了几行
5.2 SQL中的四种隔离级别
首先,因为脏写这个问题太严重了,不论是哪种隔离级别,都不允许脏写的情况发生
READ UNCOMMITTED
:读未提交READ COMMITTED
:读已提交,这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)REPEATABLE READ
:可重复读,这是MySQL默认的隔离级别SERIALIZABLE
:可串行化
MySQL对于上述4种隔离级别都是支持的,Oracle只支持 READ COMMITTED
和 SERIALIZABLE
#查看事务的隔离级别,不同MySQL版本中都可以使用的:
SELECT @@transaction_isolation;