数据库隔离机制,要看事务!!!(两个事务读到的数据不一致不能算脏读什么的,只能是同一个数据读到的不一致。或者你一个读取的事务插到人家正在update的事务中了就是脏读。)
先说几个并发时候容易出现的问题:
1、更新丢失
分为两类 第一类,
覆盖丢失
(最后提交的事务B会覆盖B事务执行过程中的别的事务进行的修改):比如一个链接是要去改name,load一个name1,age1两个数据出来,修改了之后,事务还没提交的时候,又来了一个链接,load了同样的一个name1,age1出去,等第一个请求事务提交了之后,name1改成name2,age1还是age1,。然后第二个链接修改了age1是age2,name1还是name1,提交事务,修改了之后,数据库中是name1,age2.也就是说第一个连接做的修改是无效的。
2、回滚丢失 写的事务中插入写的事务 ( 关键词:一条事务A回滚的时候,会把此时别的事务的修改覆盖,还原成A事务开始时候的数据),比如银行里面,一个连接进来,从银行里取了100块,银行账户少了100元,从1000变成900了,准备转账到另外一个账户的时候发生了错误,所以事务回滚,900再变成1000.
但是问题是,如果这个1000剪成900的时候有一个连接进来,读取到了900元的数据库信息,准备往里面存100元,然后把总价设定成1000元。但是在这之前如果事务回滚已经设置成1000元。按理说再存100应该是1100,但是此时读取的是900,存100之后就是1000,所以会导致客户损失100元。
2.脏读:在写的事务中插入读取事务
//3和4是同一个事务两次读取。
3.不可重复读取, 在读的事务中插入写的事务 我一个事务读取这条数据两次,但是却不一致,因为你在我事务期间update了。
4.幻读: 在读的事务中插入增删的事务 我一个事务对数据库进行两次查询,但是数据数目不一样,因为你在我事务期间增或者删了。
解决办法:数据库四种隔离机制:
一:Read uncommitted :写的时候可以读。
比如回滚丢失的情况,有一个事务已经开始写某条数据了,那么只允许其他事务查询,不允许其他事务修改。因为像这种回滚的事务执行的时间一般会很长,直接存款的事务很短,一般会落在有可能回滚的事务的内部。这样可以避免回滚丢失。但是这样的话我写的时候你能读,就会发生脏读。而且我写之前你读了,写之后你再读,就是不可重复读。我写的时候你读,读完了你再写,就是第二类更新丢失。但是我写的时候你读,那么会读出来多出来或者少一部分数据。这就幻读了。
二:read committed 写的时候不能读。
这样就避免了脏读,因为脏读是在一个写的事务中间插入读的事务。读的事务中间插入写,不算脏读。但是我同一个事务的两次读的时候你要是增删了,那就会导致我不可重复读,和幻读。
三:Repeatable read 读的时候不能写。
这样的话脏读肯定是不会,而且我读的时候你不能写,那么我就不会不可重复读。我读的时候虽然你不能写但是你能删增,所以还是有可能造成我幻读。
四:Serializable:我操作的时候你什么都不能做。
这样什么乱起八糟的是都没了,就是效率低了