比较复杂,执行时间较长,在可能的情况下可以通过使用中间表等措施对 语句做一定
的“分解”,使每一步查询都能在较短时间完成,从而减少锁冲突。如果复杂查询不可避免
应尽量安排在数据库空闲时段执行,比如一些定期统计可以安排在夜间执行。
锁问题
与 的最大不同有两点:一是支持事务(&F&F);二是采用了
行级锁。行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题
下面我们先介绍一点背景知识,然后详细讨论 的锁问题。
背景知识
<.事务(&!(A)及其 属性
事务是由一组 语句组成的逻辑处理单元,事务具有以下 J 个属性,通常简称为事
务的 属性。
原子性(*):事务是一个原子操作单元,其对数据的修改,要么全都执行,
要么全都不执行。
一致性((():在事务开始和完成时,数据都必须保持一致状态。这意味着所
有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的
内部数据结构(如 树索引或双向链表)也都必须是正确的。
隔离性((A):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作
影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦
然。
持久性(.!):事务完成之后,它对于数据的修改是永久性的,即使出现系统故
障也能够保持。
银行转帐就是事务的一个典型例子。
5.并发事务处理带来的问题
相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系
统的事务吞吐量,从而可以支持更多的用户。但并发事务处理也会带来一些问题,主要包
括以下几种情况。
更新丢失(( )):当两个或多个事务选择同一行,然后基于最初选定的值更
新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更
新覆盖了由其他事务所做的更新。例如,两个编辑人员制作了同一文档的电子副本。每个
编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存
其更改副本的编辑人员覆盖另一个编辑人员所做的更改。如果在一个编辑人员完成并提交
事务之前,另一个编辑人员不能访问同一文件,则可避免此问题。
脏读(! )():一个事务正在对一条记录做修改,在这个事务完成并提交前,
这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控
制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依
赖关系。这种现象被形象地叫做N脏读N。
不可重复读(F )():一个事务在读取某些数据后的某个时间,再次
读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!
这种现象就叫做“不可重复读”。
幻读(-* )():一个事务按相同的查询条件重新读取以前检索过的数据,却
发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。
#.事务隔离级别
在上面讲到的并发事务处理带来的问题中,“更新丢失”通常是应该完全避免的。但防
止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要