名词解释:事务
在实际的开发过程中,⼀个业务操作,如:转账,往往是要多次访问数据库才能完成的。转 账是⼀个⽤户扣钱,另⼀个⽤户加钱。如果其中有⼀条 SQL 语句出现异常,这条 SQL 就可 能执⾏失败。 事务执⾏是⼀个整体,所有的 SQL 语句都必须执⾏成功。如果其中有 1 条 SQL 语句出现异 常,则所有的 SQL 语句都要回滚,整个业务执⾏失败。
1.手动提交事务
功能 | SQL语句 |
开启事务 | start transaction; |
提交事务 | commit; |
回滚事务 | rollback; |
流程:
1. 执⾏成功的情况:开启事务 → 执⾏多条 SQL 语句 → 成功提交事务
2. 执⾏失败的情况:开启事务 → 执⾏多条 SQL 语句 → 事务的回滚
案例1:事务提交:
模拟张三给李四转 100 元钱(成功)
1. 使⽤ DOS 控制台进⼊ MySQL
2. 执⾏以下 SQL 语句:1.开启事务, 2.张三账号 -100, 3.李四账号 +100
3. 使⽤ Workbench 查看数据库:发现数据并没有改变
4. 在控制台执⾏ commit 提交事务;
5. 使⽤ Workbench 查看数据库:发现数据改变
案例2:事务回滚:
模拟张三给李四转 100 元钱(失败)
1. 在控制台执⾏以下 SQL 语句:1.开启事务, 2.张三账号 -500, 3.李四账号 +500
2. 使⽤ Workbench 查看数据库:发现数据并没有改变
3. 在控制台执⾏ rollback 回滚事务;
4. 使⽤ Workbench 查看数据库:发现数据没有改变
2.自动提交事务
在Mysql中, 默认每⼀条 DML(增删改)语句都是⼀个单独的事务,每条语句都会⾃动开启⼀个事务, 语句执⾏完毕⾃动提交事务,MySQL 默认开始⾃动提交事务。
3.事务原理
事务开启之后,所有的操作都会临时保存到事务⽇志中,事务⽇志只有在得到 commit 命令才会 同步到数据表中,其他任何情况都会清空事务⽇志(rollback,断开连接)。
1. 客户端连接数据库服务器,创建连接时创建此⽤户临时⽇志⽂件。
2. 开启事务以后,所有的操作都会先写⼊到临时⽇志⽂件中。
3. 所有的查询操作从表中查询,但会经过⽇志⽂件加⼯后才返回。
4. 如果事务提交则将⽇志⽂件中的数据写到表中,否则清空⽇志⽂件。
4.回滚点
在某些成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前⾯ 操作都已经成功,可以在当前成功的位置设置⼀个回滚点。可以供后续失败操作返回到该位置, ⽽不是返回所有操作,这个点称之为回滚点。
操作语句 | 语句 |
设置回滚点 | savepoint +(name) |
回到回滚点 | rollback to +(name) |
5.事务的隔离级别
5.1 事务的四大特性
事务特性 | 含义 |
原⼦性 (Atomicity) | 每个事务都是⼀个整体,不可再拆分,事务中所有的 SQL 语句要么都 执⾏成功, 要么都失败。 |
⼀致性 (Consistency) | 事务在执⾏前数据库的状态与执⾏后数据库的状态保持⼀致。 |
隔离性 (Isolation) | 事务与事务之间不应该相互影响,执⾏时保持隔离的状态。 |
持久性 (Durability) | ⼀旦事务执⾏成功,对数据库的修改是持久的。就算关机,也是保存 下来的。 |
5.2 并发操作引发的问题
并发访问的问题 | 含义 |
脏读 | ⼀个事务读取到了另⼀个事务中尚未提交的数据。 |
不可重复读 | ⼀个事务中两次读取的数据内容不⼀致,要求的是⼀个事务中多次读取时数 据是⼀致的, 这是事务 update 时引发的问题。 |
幻读 | ⼀个事务中两次读取的数据的数量不⼀致,要求在⼀个事务多次读取的数据 的数量是⼀致的, 这是 insert 或 delete 时引发的问题。 |
5.3 四种隔离级别
级别 | 名字 | 隔离级别 | 会出现的问题 |
1 | 读未提交 | read uncommitted | 脏读,不可重复读,幻读 |
2 | 读已提交 | read committed | 不可重复读,幻读 |
3 | 可重复度 | repeatableread | 幻读 |
4 | 串⾏化 | serializable | 无 |
隔离级别越⾼,性能越差,安全性越⾼。