事务是一组操作的集合,是一个不可分割的工作单位
事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,他们要么同时成功、要么同时失败,即保证原子性
默认MySQL的事务是自动提交的,当执行一条DML语句,MySQL会立即隐式的提交事务,若遇到异常则回滚事务
事务操作
查看事务提交方式:
SELECT @@autocommit;设置事务提交方式:
SET @@autocommit = 0- 1是自动提交,0是手动提交
开启事务:
START TRANSACTION;- 在自动提交的情况下可以用这个手动开启事务,接下来执行的语句不会影响数据,也可以用下面两行语句控制事务
提交事务:当设置为手动提交时需要用
COMMIT;回滚事务:
ROLLBACK;
四大特性
事务的四大特性:ACID
- Atomicity:原子性,事务是不可分割的最小操作单元,要么全部成功要么全部失败
- Consistency:一致性,事务执行前后,所有数据都必须处于一致状态
- Isolation:隔离性,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰
- Durability:持久性,事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
并发事务
并发事务问题
- 脏读:一个事务读到另一个事务还没有提交的数据
- 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同
- 幻读:一个事务按照条件查询数据时,没有对应数据行,但在插入数据时,发现数据已存在
隔离级别
对于这四种隔离级别,从上到下隔离级别越来越高,性能越来越低
- 查看事务隔离级别:
SELECT @@TRANSACTION_ISOLATION; - 设置事务隔离级别:
SET [SESSION/GLOBAL] TRANSACTION ISOLATION LEVEL {上面四种}- SESSION指对当前窗口有效,GLOBAL指对所有窗口有效
事务调度
准则
- 包含所有事物的操作指令,一个事务内指令顺序保持不变
- 并行事务调度必须保证:可串行化,将所有可能的调度推演一遍,对于某个具体并行调度再执行一遍,看是否能与某个串行调度的结果相同
- 可串行化的充分条件:冲突可串行化
封锁
X锁
写锁(排他锁),某事物对数据对象上锁后,可读取和修改该对象,其他事务不可以再对该数据对象添加锁
S锁
读锁(共享锁),某事物对数据对象上锁后,可读取但不可修改该对象,其他事务可以再对该数据对象添加S锁,不能添加X锁
封锁协议
- 一级封锁协议:写前加写锁,事务结束释放写锁
- 二级封锁协议:写前加写锁,读前加读锁,读完释放读锁,事务结束释放写锁
- 三级封锁协议:写前加写锁,读前加读锁,事务结束释放所有锁
若所有事物均遵循三级封锁协议,那么无论怎么交叉并行,都是可串行化的调度
两段锁协议(2PL)
三级封锁协议太过严苛,对并发度由负面影响
两段锁协议要求事务在任何数据进行读写前,需要对该数据封锁,而当事务在释放任何一个封锁后,不可再获得任何封锁
判断事务调度的正确性
对两个事务进行并行操作,得出结果
对两个事务进行串行操作,分别得出先T1后T2和先T2后T1的结果
若至少一个能和并行操作结果相同,则调度执行正确
对调度加锁来使得调度一致