一个数据库可能拥有多个访问客户端,这些客户端并发访问数据库时,若没有采起必要的隔离措施,存在如下问题,这些问题分为5类,包括3类数据读问题:脏读、不可重复读和幻读。两类数据更新问题:第一类丢失更新、第二类丢失更新。sql
1.脏读
A事务读取B事务还没有提交的更改数据,并在这个数据的基础上进行操做,这时候若是事务B回滚,那么A事务读到的数据是不被认可的。例如常见的取款事务和转帐事务: 数据库
2.不可重复读
不可重复读是指A事务读取了B事务已经提交的更改数据。假如A在取款事务的过程当中,B往该帐户转帐100,A两次读取的余额发生不一致。并发
3.幻读
A事务读取B事务提交的新增数据,会引起幻读问题。幻读通常发生在计算统计数据的事务中,例如银行系统在同一个事务中两次统计存款帐户的总金额,在两次统计中,恰好新增了一个存款帐户,存入了100,这时候两次统计的总金额不一致。 oracle
注意:不可重复读和幻读的区别是:前者是指读到了已经提交的事务的更改数据(修改或删除),后者是指读到了其余已经提交事务的新增数据。对于这两种问题解决采用不一样的办法,防止读到更改数据,只需对操做的数据添加行级锁,防止操做中的数据发生变化;二防止读到新增数据,每每须要添加表级锁,将整张表锁定,防止新增数据(oracle采用多版本数据的方式实现)。3d
4.第一类丢失更新
A事务撤销时,把已经提交的B事务的更新数据覆盖了。例如: 对象
这时候取款事务A撤销事务,余额恢复为1000,这就丢失了更新。blog
5.第二类丢失更新
A事务覆盖B事务已经提交的数据,形成B事务所作的操做丢失 事务
为了解决上述问题,数据库经过锁机制解决并发访问的问题。根据锁定对象不一样:分为行级锁和表级锁;根据并发事务锁定的关系上看:分为共享锁定和独占锁定,共享锁定会防止独占锁定但容许其余的共享锁定。而独占锁定既防止共享锁定也防止其余独占锁定。为了更改数据,数据库必须在进行更改的行上施加行独占锁定,insert、update、delete和selsct for update语句都会隐式采用必要的行锁定。class
可是直接使用锁机制管理是很复杂的,基于锁机制,数据库给用户提供了不一样的事务隔离级别,只要设置了事务隔离级别,数据库就会分析事务中的sql语句而后自动选择合适的锁。
不一样的隔离级别对并发问题的解决状况如图: 基础
注意:事务的隔离级别和数据库并发性是成反比的,隔离级别越高,并发性越低。