1、事务的基本特性
- 原子性 (Atomicity):事务的操作要么一起成功,要么一起失败。如果执行过程中出错,需要回滚到之前的状态。
- 一致性 (Consistency):事务完成前后,数据库的完整性约束不能被破环。例如A给B转账,不能A扣了钱,B却没有收到钱,此时的金额总数也不一致。
- 隔离性 (Isolation):同一时间,只允许一个事务请求统一数据,不同事务间应该相互干扰。例如A在银行取钱,在其取钱过程结束前,其他人不能像这张卡转账。
- 持久性 (Durability):事务完成之后,数据的更改将持久化到数据库中,不可回滚。
2、四种隔离级别对脏读、不可重复读、幻读的解决程度
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 (READ-UNCOMMITTED) | 可能 | 可能 | 可能 |
不可重复读/读提交(READ-COMMITTED) | 不可能 | 可能 | 可能 |
可重复读(REPEATABLE-READ) | 不可能 | 不可能 | 可能 |
串行化 (SERIALIZABLE) | 不可能 | 不可能 | 不可能 |
这四种级别由上至下,隔离强度逐渐增强,性能逐渐变差。它们没有绝对的优劣,采取哪种应该根据系统需求决定。MySQL默认级别为:可重复读。
串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。
3、脏读、可重复读、不可重复读与幻读
- 脏读:在一个事务中读到了另一个事务修改但未提交的数据,这些数据可能会回滚即最终可能不会持久化到数据库中。简言之,读到了并不一定最终存在的数据。
- 可重复读:在一个事务内的任意时刻,读到的同一批数据是一致的。即不受其他事务修改数据的影响,即使其他事务已经修改数据并提交事务,本事务读到的数据依然和之前一致。通常针对UPDATE操作。
- 不可重复读(读提交):在一个事务内,不同时刻读到的同一批数据可能是不同的。若其他事务已经修改数据并提交事务,此时读到的便是其他修改后的数据。通常针对UPDATE操作。
- 幻读:在一个事务中,查询同一批数据,但后面的查询查到了前面没有查到的行。这是由于其他事务中插入数据造成的,通常针对INSERT操作。
MySQL在其默认隔离级别即可重复读状态下已经解决了幻读问题。
不要混淆幻读与不可重复读,两者极其相似。但是前者针对INSERT操作,后者针对UPDATE操作。
4、SQL操作
- 查看隔离级别
select @@transaction_isolation;
# 或者使用模糊查询,查询变量
show variables like '%_isolation%';
- 更改隔离级别
set session transaction isolation level read uncommitted;
# session为事务隔离级别的范围,即当前会话。
# 与之对应的还有global,即全局范围。global设置的范围只对新的session窗口有效,修改之前已经开启的会话不受影响。
# read uncommitted为设置的隔离级别——读未提交。
- 事务操作相关SQL语句
# 开启事务
start transaction;
# 事务回滚
rollback;
# 事务提交
commit;
Q.E.D.