Mysql事务
1. 事务的概念
如果一个业务操作中有多条DML语句增删改执行,如:转账操作。有两条DML执行。这所有的DML语句必须全部执行成功,如果有一条语句执行失败。已经执行的SQL语句要进行回滚,回到没有执行前的状态。要么所有的SQL语句全部执行成功,要么全部执行失败。称为事务。
四大特性
名称 | 含义 |
---|---|
原子性 | 一个事务不可分割,要么全部成功,要么失败回滚。 |
一致性 | 事务提交前和提交后数据库状态是一致的。 |
隔离性 | 有多个事务对同一个表进行操作时,事务和事务之间不会相互影响。 |
持久性 | 事务提交后所造成的改变会永久保存到数据库中。 |
2. Mysql手动提交事务
Mysql默认自动提交事务,每执行完一条语句就把它提交数据库。
手动提交事务的逻辑如下
具体的SQL语句
功能 | SQL语句 |
---|---|
开启事务 | start transaction |
提交 | commit |
回滚 | rollback |
Mysql事务原理
- 客户端连接数据库之后,MySQL服务端会为用户自动创建临时日志文件
- 没有开启手动提交事务进行操作时,服务端会将SQL语句执行直接写到数据库中,不使用日志文件。
- 开启事务之后,所有的写操作会写到日志文件中,查询操作会经过日志文件加工再返回给客户端。
- 使用commit和rollrack结束事务并清空日志文件,commit会直接将日志文件的操作写到数据库,rollback直接清空日志文件。
3. 事务的隔离级别
隔离性:事务隔离性指事务和事务之间不相互影响。这是一种理想状况,在事务并发访问时会出现问题。
3.1 并发访问问题
并发访问指多个事务同时访问同一条记录。
并发访问的三个问题
并发访问的问题 | 说明 |
---|---|
脏读 | 一个事务读到另一个事务未提交的数据。 |
不可重复读 | 同一个事务中多次读取同一条记录,发生多次读取数据不一致的情况。 原因:因为一个事务在查询,另一个事务在更新这条记录 |
幻读 | 一个事务多次统计结果出现不同的情况。 原因:一个事务在统计记录行数,另一个事务在插入或删除记录。 |
脏读
T2读到T1未提交的数据
不可重复读
T2事务两次读取同一个变量 var 得到的数据不一致。
幻读
T1两次读取Customer的数目不一致。
3.2 隔离级别
为了消除并发访问带来的问题,我们需要设置事务的隔离级别。
隔离级别 | 含义 |
---|---|
读未提交 | 一个事务可以读到另一个事务未提交的数据。 |
读已提交 | 一个事务只能读到另一个事务已经提交的数据。 |
可重复读 | 在一个事务不管查询多少次都能得到相同的结果。 |
串行化 | 事务和事务之间只能顺序执行。 |
级别 | 名称 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommited | 是 | 是 | 是 | |
2 | 读已提交 | read commited | 否 | 是 | 是 | Oracle和SQL Server |
3 | 可重复读 | repeatable read | 否 | 否 | 是 | Mysql |
4 | 串行化 | serializable | 否 | 否 | 否 |
3.3 mysql关于隔离级别的命令
查询隔离级别
select @@tx_isolation
设置全局事务隔离级别
set global transaction isolation level 隔离级别