数据库的并发问题,可以简化成两个事务操作数据库,可以分为三种情况:
1.两个事务都在读数据库:这种情况并不会产生并发问题;
2.一个事务在读数据库,另一个事务在写数据库;
3.两个事务都在写数据库
第二种情况
如果两个事务对数据库一读一写,可能就会造成我们常说的脏读、不可重复读、幻读的问题:
脏读:一个事务读到了其他事务没有提交的数据。
不可重复读:一个事务更新了数据,使得另一个事务在同一次事务中查询的数据不一致。
幻读:一个事务插入了数据,使得另一个事务在同一次事务中查询的数据不一致。
数据库提供了4种不同的隔离级别,来解决或部分解决上述问题:
读未提交:这种隔离级别会出现上述三种问题;
读已提交:可以防止脏读,但是仍然可能会出现不可重复读和幻读的问题,这是oracle默认的隔离级别;
可重复读:可以防止脏读和不可重复读,仍然避免不了幻读,这是mysql的默认隔离级别;
序列化:也叫串行化,可以防止上述三种问题。
第三种情况
两个事务都对数据库做读操作可能会造成更新丢失。
假想场景:A事务开启,B事务开启,然后B事务向账户加了100元后提交,然后B事务也向账户加了100元,这时候B事务有两种选择,提交或者回滚,如果B事务提交,那么账户中应该多200元,但事实上只多了100元,如果B事务回滚,那么账户应该多100元,但事实上并没有多。
上述场景就更新丢失,即一个事务的写操作被其他事务的写操作的提交或回滚抹去了。
注意:无论是mysql还是oracle还是其他常用的数据库,更新丢失和脏读等问题都已经做了很好的处理,不需要我们操心。