事务
1. 含义
事务是一种机制、一个操作序列 , 由一条或多条 sql 语句组成的一个执行单位。 一组 sql 语句要么都执行要么都不执行(遵循原子性)
事务是一个不可分割的工作逻辑单位
2. 特点 【 ACID 】
- 原子性 【 Atomicity 】 :一个事务是不可再分割的整体,要么都执行要么都不执行(失败也都失败)
- 一致性 【 Consisytency 】:事务完成时,必须使所有的数据都保持一致状态
- 隔离性 【 lsolation 】:一个事务不受其他事务的干扰,多个事物之间相互隔离,操作的可见性
- 持久性 【 Durability】:事务一但提交 或 回滚, 他对数据库中的数据改变是永久的
3. 事务的使用步骤
隐式(自动)事务:没有明显的开启和结束,本身就是一条事务可以自动提交,比如insert、update、delete
显式事务:具有明显的开启和结束
使用显示事务
开启事务
START TRANSACTION; BEGIN;
设置回滚点
savepiont 回滚点名;
提交事务
commit;
回滚事务
rollback; 回滚到指定的地方 : rollback to 回滚点名;
-
查询默认提交方式
- SELECT @@autocommit;
查询到的结果是1 则表示自动提交,结果是0表示手动提交。
-
修改提交方式
- SELECT @@autocommit=0;
4. 并发事务
事务的并发问题是如何发生的?
多个事务同时操作一个数据库的相同数据时
并发问题有哪些?
- 脏读 【 Dirty Read 】 一个事务读取到了其他事务 "更新" 未提交的数据
如上图,Session A和Session B各开启了一个事务,Session B中的事务先将number列为1的记 录的name列更新为'关羽',然后Session A中的事务再去查询这条number为1的记录,如果读到 列name的值为'关羽',而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于 读到了一个不存在的数据,这种现象就称之为脏读。
- 不可重复读 【 Non-Repeatable Read 】 一个事务多次读取 (其他事务 " 更新 " 的数据),结果不一样
如上图,我们在Session B中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提 交了),这些事务都修改了number列为1的记录的列name的值,每次事务提交之后,如果 Session A中的事务都可以查看到最新的值,这种现象也被称之为不可重复读。
- 幻读 【 Phantom 】 一个事务读取了其他事务还没有提交的数据 (其他事务新 " 插入" 的数据)
如上图,Session A中的事务先根据条件number > 0这个条件查询表hero,得到了name列值 为'刘备'的记录;之后Session B中提交了一个隐式事务,该事务向表hero中插入了一条新记 录;之后Session A中的事务再根据相同的条件number > 0查询表hero,得到的结果集中包含 Session B中的事务新插入的那条记录,这种现象也被称之为幻读。
那如果Session B中是删除了一些符合number > 0的记录而不是插入新记 录,那Session A中之后再根据number > 0的条件读取的记录变少了,这种现象算不算幻读呢? 明确说一下,这种现象不属于幻读,幻读强调的是一个事务按照某个相同条件多次读取记录时, 后读取时读到了之前没有读到的记录。 那对于先前已经读到的记录,之后又读取不到这种情况,算啥呢? 其实这相当于对每一条记录都 发生了不可重复读的现象。幻读只是重点强调了读取到了之前读取没有获到的记录
并发事务的严重程度
脏读 > 不可重复读 > 幻读
如何解决并发问题
通过设置隔离级别来解决并发问题
5. 事务的隔离级别
READ UNCOMMITTED:未提交读。
READ COMMITTED:读已提交。
REPEATABLE READ:可重复读。
SERIALIZABLE:可串行化。
隔离级别能解决的并发问题
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED 【 ru 】:未提交读 | × | x | x |
| READ COMMITTED 【 rc 】:读已提交 | √ | x | x |
| REPEATABLE READ 【 rr 】:可重复读。 | √ | √ | x |
| SERIALIZABLE :可串行化。 | √ | √ | √ |
也就是说 READ UNCOMMITTED 隔离级别下,可能发生脏读、不可重复读和幻读问题。 READ COMMITTED 隔离级别下,可能发生不可重复读和幻读问题,但是不可以发生脏读问题。 REPEATABLE READ 隔离级别下,可能发生幻读问题,但是不可以发生脏读和不可重复读的问 题。 SERIALIZABLE隔离级别下,各种问题都不可以发生。