数据库并发处理

数据库并发处理


**** 一、并发处理

数据库的特点就是数据的集中管理和共享。在通常情况下总是有若干个事务并发地运行,这些并行的事务可能并发地存取相同的数据。因此,数据库管理系统的一个重要任务就是要有一种机制去保证这种并发的存取和修改不破坏数据的完整性,确保这些事务能正确地运行并取得正确的结果。

我们知道,事务并发执行时若不加控制的话,将导致不正确的结果和数据库的不一致状态。为保证数据库数据正确地反映所有事务的更新,以及在一事务修改数据时其它事务不同时修改这个数据,数据库系统用锁来控制对数据的并发存取。

** 二、ORACLE 的并发处理机制 **

无需任何说明, ORACLE 自动提供行级锁,它允许用户在没有冲突的情况下更新表中不同的行。行级锁对联机事务处理非常有用。

1 、 ORACLE 锁

ORACLE 锁的类型在正常情况下, ORACLE 会自动锁住需要加锁的资源以保护数据,

这种锁是隐含的,叫隐含锁。然而,在一些条件下,这些自动的锁在实际应用时并不能满足需要,必须人工加一些锁。这些人工加的锁叫显示锁。

下面指明了会产生隐含锁的 SQL 语句:

INSERT ;

UPDATE ;

DELETE ;

DDL/DCL 语句。

下面指明了会产生显示锁的 SQL 语句:

SELECT FOR UPDATE ;

LOCK TABLE INXXX MODE 。

解决读的不可重复性可以用下面的方法。在 ORACLE 中,用 SELECT FOR UPDATE 对预期要修改的记录加行排它锁( X ),对表加行共享锁( RS )。它常用于要锁住一行,但不去真的修改这一行。锁之间是有相互作用的。

例如,更新时会对表加 RX 锁,对行加 X 锁,而只有 RS 锁和 RX 锁允许再加 RX 锁。因此,当存在 RS 和 RX 锁时,表允许更新。再比如,当执行 DDL 和 DCL 语句时,会对表加排它锁 X ,而在存在 X 、 RS 、 SRX 、 RX 和 S 锁的前提下,都不能再加 X 锁。因此,当存在 X , RS , SRX , RS 或 S 锁时,不能对表做 DCL 和 DDL 操作。这样,数据库会自动防止一个用户更新表中的数据,而其他用户在同时修改表的结构。

2 、 ORACLE 只读事务

ORACLE 支持只读事务。只读事务有以下特点:

  • 在事务中只允许查询

  • 其它事务可修改和查询数据

  • 在事务中,其它用户的任何修改都看不见

只读事务的写法为:

SET TRANS ACTION READONLY

SQL 语句

COMMIT , ROLLBACK , DDL 结束只读事务

3 、事务一致性的级别

事务是定义和维护一致性的单位,封锁就是要保证这种一致性。如果对封锁的要求高会增加开销,降低并发性和效率;有的事务并不严格要求结果的质量(如用于统计的事务),如果加上严格的封锁则是不必要和不经济的。因此有必要进行进一步的分析,考察不同级别的一致性对数据库数据的质量及并行能力的影响。

一致性级别定义为如下的几个条件:

  1. 事务不修改其它任何事务的脏数据。脏数据是被其它事务修改过,但尚未提交的数据。

  2. 在事务结束前不对被修改的资源解锁。

  3. 事务不读其它任何事务的脏数据。

  4. 在读前对数据加共享锁( RS )和行排它锁,直至事务结束。

  • 满足条件 1 的事务叫第 0 级事务。

  • 满足条件 1 和 2 的事务叫第 1 级一致性事务。

  • 满足条件 1 、 2 和 3 的事务为 2 级一致性事务。

ORACLE 的读一致性保证了事务不读其它事务的脏数据。

  • 满足条件 1 、 2 、 3 和 4 的事务叫第 3 级一致性事务。

由 ORACLE 的三个性质:自动加隐式锁、在事务结束时释放锁和读一致性,使 ORACLE 成为自动满足以上的 0 、 1 和 2 级一致性事务。因此, ORACLE 自动防止了脏读(写 - 读依赖)。但是, ORACLE 不能自动防止丢失修改(写 - 写依赖),读的不可重复性(读 - 写依赖),彻底解决并发性中的问题还需满足第 4 个条件( 3 级一致性事务),这需要程序员根据实际情况编程。

方法如下:

  • 如果想在一段时间内使一些数据不被其它事务改变,且在本事务内仅仅查询数据,则可用 SETTRANSACTIONREADONLY 语句达到这一目的。

  • 如果想在一事务内修改一数据,且避免丢失修改,则应在读这一数据前用 SELECTFORUPDATE 对该数据加锁。

  • 如果想在一事务内读一数据,且想基于这一数据对其它数据修改,则应在读数据前对此数据用 SELECTFORUPDATE 加锁。对此种类型的应用,用这条 SQL 语句加锁最恰当。

  • 如果想避免不可重复读现象,可在读前用 SELECTFORUPDATE 对数据加锁,或用 SET TRANS ACTION READONLY 设置只读事务。

** 三、SYBASE 的并发处理机制 **

SYBASE 的并发处理方法与 ORACLE 类似,但在很多方面不一样。 SYBASE 有两种粒度的封锁,一种的粒度是页,另一种的粒度是表。 SYBASE 根据 SQL 语句的情况决定用页封锁还是用表封锁。

1 、页级锁

页级锁有以下所始的三类:

*SHARED :在读操作时加共享锁。在缺省状态下,在读操作完成后释放共享锁。

*EXCLUSIVE :在更新操作时加排它锁。在缺省状态下,在事务完成后释放排它锁。

*UPDATE :在修改和删除操作的初期(读到被修改或删除的页时)加修改锁。在表上加了修改锁之后,还可以再加共享锁,但不能再加修改和排它锁。在进行修改和删除操作时,如果没有共享锁存在,修改锁则转化为排它锁。此锁的目的是为了防止死锁。 SYBASE 仅当在 WHERE 子句中包含索引列时才会使用页级的排它锁和修改锁。

2 、表级锁

表级锁有以下所示的三类:

*INTENT :当表中存在页级的排它锁和共享锁时,在表上加意向锁。在所有的页级锁释放后,意向锁随着释放。

*SHARED :在读操作时加共享锁。在缺省状态下,在读操作完成后释放共享锁。

*EXCLUSIVE :在更新操作时加排它锁。在缺省状态下,在事务完成后释放排它锁。

3 、请求锁

请求锁用以防止共享锁一个接一个无休止地加在表上,从而写事务(要加排它锁)无法进行。

4 、 SYBASE 的封锁级别

在 SYBASE 根据 ANSI 标准定义事务的封锁级别:

(1) 级别 1 :脏读

(2) (2) 级别 2 :不可重复读

(3) (3) 光标带来的当前值混乱

(4) SYBASE 的缺省一致性级别为 1 。

如果要达到一致性级别 2 和 3 ,必须使用 HOLDLOCK 关键字把共享锁持续到事务的结束。方法如下:

SELECT*FROM AUTHS HOLDLOCK

WHERE AUTHOR_CODE='A00001'

SYBASE 还可以通过 T-SQL 的 SET 命令改变 SYBASE 的一致性级别,从而使 SYBASE 自动在 SELECT 语句中加 HOLDLOCK 关键字:

SET TRANS ACTION IS OLATION LEVEL3

5 、在 SYBASE 中提高并发效率的方法

  • 避免在表中特定的页上多个用户过多的封锁。

  • 避免在人机交互的应用中定义事务,这样会使某个用户长时间封锁

住表(如去接电话),使其他用户持续等待。

  • 使事务尽量的短。

  • 仅当必要时才使用 HOLDLOCK 关键字。

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus