建立一个 Derby 日历,第 3 部分: 使用事务和锁定(上)
2010-04-19 00:00:00 来源:WEB开发网脏读(dirty read)
如果一个用户修改了数据库中的数据,在提交修改之前这些数据被认为是脏 的。因为修改可能随时滚回,不能看作是永久性的,因此当另一个事务查看脏的数据时就被认为是一种异常。
原因:一个事务选择另一个事务已修改但没有提交的数据。
不可重复读(nonrepeatable read)
从数据库中选择数据时,我们期望数据还回到数据库中。比如,如果取得了某一天的事件列表,当然会希望根据这些数据作出决策。如果事务查看的数据不再存在于数据库中就会出现不可重复读。
原因:一个事务选择了一组数据,但是在该事务处于活动状态或者说没有提交之前,另一个事务修改了这些数据。
虚读(phantom read)
从期望看到的数据和数据库中一致这方面来说,这种异常与不可重复读 类似。但这种情况下,问题在于插入数据 而非修改数据。比如,假设您选择了 2005 年 10 月 28 日的所有事件,在您查看的时候,我增加了一个应该属于该查询结果的事件,这条记录被排除在外,这就是虚读。
原因:一个事务选择了一组数据。但该事务处于活动状态时,另一个事务插入了应属于该结果集的数据。
数据库锁
为了防止这些异常,数据库建立了锁定系统。当事务对数据库操作时,包括 select 语句,通常必须首先请求适当的锁。什么类型的锁适用于什么情况依赖于几方面的因素,包括 隔离级别。但首先必须了解有哪些类型的锁。
共享锁
事务选择数据时通常首先请求共享(shared)锁。如果第二个事务希望选择同一些数据,也可以得到共享锁。如果具有共享锁的事务希望修改数据,首先必须将锁转化成独占(exclusive)锁。
独占锁
当事务修改数据时,必须首先申请独占 锁来锁定数据。一旦锁定,其他事务就不能再锁定该数据,也就不能修改这些数据。使用独占锁之后,也不能再增加共享锁,因此其他事务不能再选择这些数据。
更多精彩
赞助商链接