数据库(MySQL):事务

1. 什么是事务

事务是逻辑上的一组操作,要么都执行,要么都不执行。

2. 事务的四大特性(ACID)

  • A 原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • C 一致性(Consistency):事务执行前后,数据保持一致,多个事务对同一个数据读取的结果是相同的。
  • I 隔离性(Isolation):并发访问数据库时,一个用户的事务不受其他事务的干扰,各并发事务之间数据库是独立的。
  • D 持久性(Durability):一个事务被提交后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

3. 事务并发带来的数据不一致性

  • 脏读(dirty read):事务1访问并修改了某个数据,但尚未提交到数据库,这时事务2访问了这个数据,然后使用了这个数据。由于这个数据还没有提交,可能事务1的这个修改会被撤销,这个数据被恢复原值,事务2读到的值可能与数据库不一致。事务2读到的数据可能为“脏”数据,即不正确的数据。
  • 丢失修改(lost update):事务1和事务2同时修改了某个数据,事务2的提交结果破坏了事务1的提交结果,导致事务1的修改被丢失。
  • 不可重复读(non-repeatable read):有三种情况(后两种情况也称幻读):
    a. 事务1读某个值后,事务2修改了这个值,事务1再次读时,发现与之前读的值不同。
  • 幻读
    b. 事务1按条件从数据库读取某些记录后,事务2删除了其中部分记录,事务1再次按相同条件读取时,发现某些记录神秘的消失了。
    c. 事务1按条件从数据库读取某些记录后,事务2添加了某些记录,事务1再次按相同条件读取时,发现多了一些记录。

4. 事务隔离级别

为解决以上事务并发带来的问题,标准SQL规范定义了4种隔离级别,不同隔离级别对事务的处理不同。

  • 读未提交(RU: READ-UNCOMMITED):允许读未提交的数据变更。可能会导致脏读、不可重复读、幻读。
  • 读已提交(RC: READ-COMMITED):允许读并发事务已提交的数据。可以防止脏读,但可能会发生不可重复读、幻读。
  • 可重复读(RR: REPEATABLE-READ):对同一字段的多次读取得到的数据是一致的,除非数据是被本身事务自己修改的。可以防止脏读、不可重复读,但可能会发生幻读。
  • 可串行化(SERIALIZABLE):完全符合事务的ACID特性,逐个执行各个事务,事务之间完全不会互相干扰。可以防止脏读、不可重复读、幻读。

发现:都未特别说明对 丢失修改 问题进行的处理。
2

5. MySQL的默认隔离级别

MySQL InnoDB存储引擎的默认隔离级别是可重复读,可通过 SELECT @@tx_isolation来查看。

其使用的NEXT KEY LOCK,可完全避免幻读。

6. 锁机制

  • 表级锁:MySQL中粒度最大的一种锁,对当前操作的整张表加锁,并发度低,开销小,加锁快,不会出现死锁。
  • 行级锁:MySQL中粒度最小的一种锁,对当前操作的行加锁,并发度高,开销大,加锁慢,会出现死锁。

InnoDB锁算法有以下三种:

  • Record lock:当个行记录上的锁(当查询的索引含有唯一属性时,Next-key lock降为 Record lock)
  • Gap lock:间隙锁,锁定一个范围,不包含记录本身(防止多个事务将记录插入到同一范围内,这会导致幻读产生)
  • Next-key lock:record+gap,锁定一个范围,包含记录本身 (InnoDB对于行的查询使用Next-key lock;Next-locking keying为了解决幻读问题)
posted @ 2021-09-02 16:51  aguo718  阅读(100)  评论(1编辑  收藏  举报