3、事务的隔离级别
1)潜在问题
事务为什么需要多种可以设置的隔离级别呢?通常,锁可以实现并发操作中事务的隔离,保证数据的一致性。锁提高了并发性能,但会带来潜在的问题:
脏读:当前事务可以读到另外一个事务中未提交的数据。
不可重复读:在一个事务内读到的同一条数据是不一样的。
幻读:事务A在相同条件下第二次读取时读到新插入的数据。
丢失更新:一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致。 例如:
事务T1将行记录修改为V1,事务T1未提交。
事务T2将行记录修改为V2,事务T2未提交。
事务T1提交。
事务T2提交。
在当前数据库的锁机制下不会导致理论意义上的丢失更新问题,但是实际上在所有多用户计算机系统环境下都有可能产生这个问题。例如:
事务T1查询一行数据,放入本地内存,显示给User1。
事务T2查询一行数据,放入本地内存,显示给User2。
User1修改这行记录,更新数据库并提交。
User2修改这行记录,更新数据库并提交。
这些问题往往和系统数据库的使用方式和形态有关。而设置事务的隔离级别,就是根据不同的场景来解决以上问题。比如上面所说的丢失更新问题,隔离级别中SELECT…FOR UPDATE即带有更新意图读的时候,步骤1、2都是要上写锁的,避免丢失更新的问题。下面详解数据库的隔离级别及其加锁方式。
2)数据库的隔离级别及其加锁方式
① SQL标准定义的四个隔离级别
READ UNCOMMITTED:未提交读。事务可以看到其他事务所有未提交的数据。读取数据不加锁;
READ COMMITTED:提交读。事务只可以看到其他事务已经提交的数据;
REPEATABLE READ:重复度。锁定事务引用的符合检索条件的部分行,其他事务不可修改这些行,但可执行INSERT操作。即可能出现幻读;