事务的四大特征
-
原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
-
一致性(Consistency): 执行事务后,数据库从一个正确的状态变化到另一个正确的状态;
-
隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
-
持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
并发事务带来哪些问题
脏读
假设事务 A 更新了一行数据的值为 A 值,但并没有提交,此时事务 B 去查询了一下这行数据的值,看到的值是 A 值,然后事务B去拿A值去做各种操作,但是A又对A值进行了修改,导致B拿错误的值做了很多操作。
丢失修改
事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
不可重复读
比如A在查看余额,第一次查看账户余额为300, 此时B又对账户取款300,A第二次查看账户发现为0。
幻读
简单来说,你一个事务 A,先发送一条 SQL 语句,里面有一个条件,要查询一批数据出来,如 SELECT * FROM table WHERE id > 10
。然后呢,它一开始查询出来了 10 条数据。接着这个时候,别的事务 B往表里插了几条数据,而且事务 B 还提交了,此时多了几行数据。
接着事务 A 此时第二次查询,再次按照之前的一模一样的条件执行 SELECT * FROM table WHERE id > 10
这条 SQL 语句,由于其他事务插入了几条数据,导致这次它查询出来了 12 条数据。
幻读与不可重复读类似,幻读是增加了或缺少了几行数据,不可重复读是修改了单条数据。
事务隔离级别有哪些?MySQL的默认隔离级别是?
SQL 标准定义了四个隔离级别:
-
READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
-
READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
-
REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
-
SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
InnoDB存储引擎的锁的算法有三种:
-
Record lock:单个行记录上的锁
-
Gap lock:间隙锁,锁定一个范围,不包括记录本身
-
Next-key lock:record+gap 锁定一个范围,包含记录本身
Next-key lock 即这行以及这一片的数据,都被锁住。