MySQL:事务控制语言(TCL)
目录
参考:
# MySQL:事务控制语言(TCL)
事务:一个或一组sql语句组成的最小执行单元,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。
数据库事务是保证在并发情况下能够正确执行的重要支撑,MySQL常见的数据库引擎中支持事务的是InnoDB。
事务要保证能够正常的执行,就必须要保持ACID特性:
- 原子性(Atomicity):一个事务不可在被分割,要么都执行、要么都不执行;
- 一致性(Consistency):一个事务会使数据从一个一致状态切换到另一个一致状态;
- 隔离性(Isolation):一个事务的执行不受其他事务的干扰
- 持久性(Durability):一个事务一旦提交,在会永久的改变数据库的数据。
# 一、事务的创建
# 隐式事务
隐式事务没有明显的开启和结束的标记,即:执行DML无需手动开启和提交事务。
比如:insert、udate、delete语句
# 显示事务
显示事务具有明显的开启和结束的标记,前提:必须先设置自动提交为禁用。
步骤一:开启事务
set autcommit = 0;(默认值是1,也就是默认自动开启提交)
start transation;
步骤二:编写事务中的sql语句(select、insert、update、delete)
语句1;
语句2;
...
步骤三:结束事务 根据情况选择是提交事务还是回滚事务
commit;提交事务
或
rollback;回滚事务
2
3
4
5
6
7
8
9
10
11
# 二、事务隔离级别
当同时存在多个事务时,这些事务共同访问数据库中的相同数据时,如果不采取必要的隔离机制,就有极大的可能出现各种并发问题:
脏读:对于两个事务T1、T2,T1读取了已被T2更新但还未提交的字段,之后若T2回滚,T1 读取的内容就是临时且无效的。
不可重复读:对于两个事务T1、T2,T1读取了一个字段,然后T2更新了该字段之后,T1再次读取同一个字段,值就不同了。
幻读:对于两个事务T1、T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新数据之后,T1再次读取同一个表,就会多出几行来。
不可重复读与幻读的区别:不可重复读主要体现在update,即事务前后对特定字段的内容的修改;而幻读体现在insert和delete,即事务前后对整个数据结果集的对比。
数据库提供的4种事务隔离级别:
隔离级别 | 说明 | 脏读 | 不可重复读 | 幻读 | 描述 |
---|---|---|---|---|---|
READ UNVCOMMITED | 读未提交数据 | √ | √ | √ | 允许事务读取未被其他事务提交的变更 |
READ COMMITED | 读已提交数据 | × | √ | √ | 只允许事务读取已经被其他事务提交的变更 |
REPEATABLE READ | 可重复读 | × | × | √ | 确保事务可以从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新 |
SERIALIZABLE | 串行化 | × | × | × | 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、删除、更新和操作,可以避免所有的并发问题,但性能十分低下 |
MySQL支持以上四种事务隔离级别,且将repeatable read
设置为默认隔离级别。
Oracle支持两种事务级别:read commited
和serializable
,且将read commited
设置为默认隔离级别。
# 三、MySQL中设置隔离级别
每启动一个mysql程序,就会有一个全局变量@@tx_isolation,表示当前的事务隔离级别。
-- 查看当前的隔离级别:
SELECT @@tx_isolation;
-- 设置当前mysql连接的隔离级别:
SET TRANSACTION ISOLATION LEVEL 隔离级别名称;
2
3
4