1.数据库的三种数据不一致问题
1.1 更新丢失:两个事务操作同一条数据,数据被覆盖
1.2 脏读:一个事务读到了另一个事务未提交的数据,改数据在任何一个事务里面都不是最终态
1.3 不可重复读:一个事务,对数据两次查询,结果不一致
(1) 虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
2 数据库事务隔离级别
2.1 读未提交(read uncommitted):读的事务操作的数据,可以被其他事务进行读写操作;写的事务操作的数据,不可以被其他事务写,可以被读到。导致读的事务,读到了未提交的写事务。只能避免更新丢失
2.2 读已提交(read committed): 读的事务操作的数据,可以被其他事务进行读写;写的事务操作的数据,不可以被其他事务进行任何操作。导致写的事务,未完成前,不可以被读到。避免了更新丢失、脏读问题
2.3 可重复读(Repeatable read): 读的事务操作的数据,只能被其他读的事务读,不能被写;写的事务操作数据,不能被其他事务操作。避免了脏读,虚度,无法避免幻读
2.4 序列化(Serializable):事务必须依次进行
3 数据库的锁
- 共享锁:读锁,当前事务读的时候,其他事务也可以读,但不能对该数据行进行增删改。
- 排它锁:写锁,当前事务写的时候,其他事务不能写 设置共享锁:SELECT … LOCK IN SHARE MODE; 设置排他锁:SELECT … FOR UPDATE;
Mysq里面的问题:
对于select 语句,innodb不会加任何锁,也就是可以多个并发去进行select的操作,不会有任何的锁冲突,因为根本没有锁。
对于insert,update,delete操作,innodb会自动给涉及到的数据加排他锁,只有查询select需要我们手动设置排他锁。