当前位置: 首页 > 科技观察

数据库常用的事务隔离级别有哪些?原则是什么?

时间:2023-03-16 21:12:10 科技观察

什么是事务隔离?任何支持事务的数据库都必须具备四个特性,即:原子性、一致性、隔离性和持久性,也就是我们常说的事务ACID,从而保证事务(Transaction)中数据的正确性。事务的隔离是指当多个并发事务同时访问一个数据库时,一个事务不应该被另一个事务干扰,每个并发事务之间应该相互隔离。如果没有事务隔离会怎样?假设我们现在有这样一张表(T),里面记录了很多伟人的名字,我们不进行事务隔离,看看会发生什么?第一天,事务A访问数据库,它做了一件事情,把新人的名字加入数据库,但是没有提交事务。insertintoTvalues(4,'牛D');这时又来了一个事务B,他想查询所有伟人的名字。selectNamefromT;这时候,如果事务之间没有有效的隔离,那么事务B返回的结果就会出现“牛D”的名字。这是“脏读”。第二天,事务A访问数据库,他想查ID为1的那个人的名字,于是执行selectNamefromTwhereID=1;这时事务B来了,因为ID为1的人改了名字,所以需要更新一下,然后提交事务。updateTsetName='不是很棒'whereID=1;然后,事务A想看ID为1的人的名字,于是又执行了一次selectNamefromTwhereID=1;结果读取了两次ID为1的master名字都不一样,这就是不可重复读(unrepeatableread)。第三天,事务A访问了数据库,他想看看数据库的master有哪些,于是执行了select*fromT;这时,事务B来了,数据库中增加了一个新的master。insertintoTvalues(4,'牛D');这个时候事务A忘记了masters刚才有什么是的,所以又执行了一次。从T中选择*;结果第一次是三个人才,第二次是四个人才。相信这时候,事务A就会一头雾水。刚刚发生了什么?这种情况称为“幻读(phantomproblem)”。为了防止脏读、不可重复读、幻读等,我们需要根据实际需要设置数据库的隔离级别。数据库的隔离级别是多少?一般的数据库包括以下四种隔离级别:未提交读(ReadUncommitted)已提交读(ReadCommitted)可重复读(RepeatedRead)可序列化(Serializable)如何使用这些隔离级别,需要根据实际情况判断这生意。下面我们就来看看这四种隔离级别的具体情况。ReadUncommitted(未提交读)ReadUncommitted,顾名思义,就是可以读到未提交的内容。因此,在这种隔离级别下,查询不会被加锁,而由于查询没有加锁,这种隔离级别的一致性是最差的,“脏读”、“不可重复读”和“不可重复读”“可能发生。”、“幻读”。除非有特殊情况,基本不用这个隔离级别。读提交(ReadCommitted),顾名思义,就是只能读取提交的内容。这是最常用的隔离各种系统中的级别,也是SQLServer和Oracle默认的隔离级别,这种隔离级别可以有效避免脏读,但是除非在查询中显示锁,如:select*fromTwhereID=2lockinsharemode;select*fromTwhereID=2forupdate;否则,普通查询是不会加锁的。那为什么“readcommitted”没有像“readuncommitted”那样的查询锁,却可以避免脏读呢?这是另一种机制“快照(snapshot)”,可以保证一致性解锁读也称为“快照读”,假设没有“快照读”,当一个更新的事务没有提交时,另一个查询更新数据的事务会因为查询不到而阻塞,阻塞,i在这种情况下,并发能力很差。但是“快照读”可以完成高并发查询。但是,“读提交”只能避免“脏读”,而不能避免“不可重复读”和“幻读”。可重复读(RepeatedRead)重复读,顾名思义,就是专门针对“不可重复读”的情况制定的隔离级别。自然可以有效避免“不可重复读”。也是MySql默认的隔离级别。在这一层,普通查询也使用“快照读”,但与“读提交”不同的是,事务开始时,不允许“更新操作(Update)”,“不可重复”,因此“可重复读”可以有效避免“不可重复读”,但不能避免“幻读”,因为幻读是由“插入或删除操作(InsertorDelete)”引起的。可序列化(Serializable)这是数据库的最高隔离级别。在这个层次上,事务是“按序列化顺序执行”的,即一个一个排队执行。在这个层次上,“脏读”、“不可重复读”、“幻读”都可以避免,但执行效率极差,性能开销大,所以基本没人会用。总结一下为什么会出现“脏读”?因为没有规则就没有“选择”操作。为什么会出现“不可重复读”?因为“更新”操作是没有规则的。为什么会出现“幻读”?因为“插入”和“删除”操作是没有规则的。“ReadUncommitted”可以防止什么?没有什么。“ReadCommitted”可以防止什么?使用“快照读”可以避免“脏读”,但可能会出现“不可重复读”和“幻读”。“重复红”能预防什么?使用“SnapshotRead”锁定读取记录,避免“脏读”和“不可重复读”,但可能会出现“幻读”。“Serializable”可以防止什么?坐成一排,吃蔬菜水果,可以有效避免“脏读”、“不可重复读”和“幻读”,但效果谁用过就知道了。