[MySQL] MySQL事务详情
Contents
数据库中的事务是指对数据库执行一批操作,这些操作最终要么全部执行成功,要么全部失败,不会存在部分成功的情况。
事务的特性(ACID)
- 原子性(Atomicity):一组事务,要么成功,要么撤回,事务是一个不可分割的整体, 不可能停滞在中间环节。 事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。
- 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。 事务开始之前、执行中、执行完毕,这些时间点,多个人去观察事务操作的数据的时候,看到的数据都是一致的
- 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。 比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
- 持久性(Durability):事务提交成功后,事务对数据库的所有更新将被保存到数据库,不能回滚。
事务的并发问题
- 脏读:一个事务在执行的过程中读取到了其他事务还没有提交的数据。事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
- 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
- 幻读: 在一个事务的两次查询中数据笔数不一致,例如事务A查询了几列(Row)数据,而事务B却在此时插入了新的几列数据, 事务A在接下来的查询中,就会发现有几列数据是它先前所没有的
不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
MySQL事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted) | 是 | 是 | 是 |
读已提交(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
- 读未提交:一个事务可以读取到,另外一个事务尚未提交的变更。
- 已提交读:一个事务提交后,其变更才会被另一个事务读取到。
- 可重复读:在一个事务执行的过程中所读取到的数据,和事务启动时所看到的一致。
- 串行化:当操作一行数据时,读写分别都会加锁。当出现读写锁互斥时,会排队串行执行。
MySQL默认的事务隔离级别为可重复读(repeatable-read)
4种隔离级别越来越强,会导致数据库的并发性也越来越低。
设置事务隔离级别
- 配置文件my.cnf [mysqld]段中设置
|
|
- 命令行选项–transaction-isolation设置
- SET TRANSACTION语句改变单个session
|
|
查看事务隔离级别
|
|
事务操作
MySQL中事务默认是隐式事务,由变量autocommit控制,开启隐式事务操作自动提交;
隐式事务
- 配置文件[mysqld]设置autocommit=1或者命令行设置
|
|
显示事务
显示事务需要手动开启、提交、回滚
- set autocommit=0; // 设置不自动提交事务
- begin; // 开启事务
- start transaction; // 存储过程中begin关键字有冲突,使用这个开启事务
- commit; // 提交操作
- rollback; // 回滚操作
savepoint
在事务中设置保存点,可以将事务分为几个部分,这样能实现回滚指定部分事务
|
|
设置保存点,id重复设置会覆盖
|
|
释放已经设置的保存点,保存点不存在时报错,重复释放同一个保存点会报错
|
|
回滚到指定的保存点,在保存点到当前的所有操作会回滚,保存点之前的操作依然可以提交,保存点不存在会报错
只读事务
只读事务过程中只能做只读操作,不能做DML等操作,否则报错;
|
|