数据库事务基础

并发事务引发的问题

1. 更新丢失(Lost Update)面试

两个事务都同时更新一行数据,可是第二个事务却中途失败退出,致使对数据的两个修改都失效了。这是由于系统没有执行任何的锁操做,所以并发事务并无被隔离开来。数据库

2. 脏读(Dirty Read)并发

又称无效数据读出。一个事务读取另一个事务尚未提交的数据叫脏读。性能

例如:事务T1修改了一行数据,可是尚未提交,这时候事务T2读取了被事务T1修改后的数据,以后事务T1由于某种缘由Rollback了,那么事务T2读取的数据就是脏的。spa

3. 不可重复读(Non-Repeatable Read)blog

是指在一个事务中两次读同一行数据,但是这两次读到的数据不同。事务

例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便获得了不一样的结果。it

4. 幻读table

事务在操做过程当中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺乏了第一次查询中出现的数据基础

例如:系统管理员A将数据库中全部学生的成绩从具体分数改成ABCDE等级,可是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉同样。这就叫幻读。

不可重复读重点在于update和delete,而幻读的重点在于insert。因此说不可重复读和幻读最大的区别,就在于如何经过锁机制来解决他们产生的问题。

事务隔离级别有哪些?

(更新丢失、脏读、不可重复读、幻读)都和事务的隔离级别有关。经过设置事务的隔离级别,能够避免上述问题的发生。

1. 读未提交(Read Uncommitted)

读事务不阻塞其余读事务和写事务,未提交的写事务阻塞其余写事务但不阻塞读事务。

此隔离级别能够防止更新丢失,但不能防止脏读、不可重复读、幻读。

此隔离级别能够经过“排他写锁”实现。

2. 读已提交(Read Committed)

读事务容许其余读事务和写事务,未提交的写事务禁止其余读事务和写事务。

此隔离级别能够防止更新丢失、脏读,但不能防止不可重复读、幻读。

此隔离级别能够经过“瞬间共享读锁”和“排他写锁”实现。

3. 可重复读取(Repeatable Read)

以操做同一行数据为前提,读事务禁止其余写事务但不阻塞读事务,未提交的写事务禁止其余读事务和写事务。

此隔离级别能够防止更新丢失、脏读、不可重复读,但不能防止幻读。

此隔离级别能够经过“共享读锁”和“排他写锁”实现。

4. 序列化(Serializable)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。

此隔离级别能够防止更新丢失、脏读、不可重复读、幻读。

若是仅仅经过“行级锁”是没法实现事务序列化的,必须经过其余机制保证新插入的数据不会被刚执行查询操做的事务访问到。

可串行化:若是一个并行调度的结果等价于某一个串行调度的结果,那么这个并行调度是可串行化的。

隔离级别越高,越能保证数据的完整性和一致性,可是对并发性能的影响也越大。对于多数应用程序,能够优先考虑把数据库系统的隔离级别设为Read Committed。它可以避免更新丢失、脏读,并且具备较好的并发性能。尽管它会致使不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,能够由应用程序采用悲观锁或乐观锁来控制。

用一张图来阐述不一样事务隔离级别在针对事务并发问题方面的解决能力:

Java面试精讲:数据库事务基础

相关文章
相关标签/搜索