-
- LOCK TABLE 语句
使用 LOCK TABLE 语句来控制通过其他进程访问表。xzzz
语法
元素 | 描述 | 限制 | 语法 |
owner | synonym 或 table 的所有者 | 必须为指定的对象的所有者 | 所有者名称 |
synonym | 要被锁定的表的同义词 | 同义词以及指向它的表必须存在 | 标识符 |
table | 要被锁定的表 | 请参阅 用法 的第一段。 | 标识符 |
用法
此语句是对 SQL 的 ANSI/ISO 标准的扩展。
如果下列任一为真,则您可使用 LOCK TABLE 来锁定表:
- 您是该表的所有者。
- 您有对该表或对该表中列的 Select 权限,或通过直接授权,或通过授权给 PUBLIC 或给您的当前角色。
如果该表已被另一进程在 EXCLUSIVE 模式下锁定,或如果您请求 EXCLUSIVE 锁而另一用户已经以 SHARE 模式锁定了同一张表,则 LOCK TABLE 语句失败。
SHARE 关键字以共享模式锁定表。共享模式允许其他进程对该表的读访问,但拒绝写访问。如果以共享模式锁定表,则其他进程不可更新或删除数据。
EXCLUSIVE 关键字以排他模式锁定表。此模式拒绝其他进程对表进行读访问,也拒绝写访问。 在下列语句期间,排他模式锁定自动地发生:
- ALTER FRAGMENT
- ALTER INDEX
- ALTER TABLE
- CREATE INDEX
- DROP INDEX
- RENAME COLUMN
- RENAME TABLE
- START VIOLATIONS TABLE
- STOP VIOLATIONS TABLE
- TRUNCATE
在一些 DDL 操作中的 ONLINE 关键字
在某些 ALTER FRAGMENT、DROP INDEX 和 CREATE INDEX 操作期间,包括 ONLINE 关键字在内,当并发的会话尝试访问同一表时,可减低运行时出错的风险。要获取更多关于支持 ONLINE 关键字选项的那些 DDL 语句的锁定行为的信息,请参阅这些主题:
- 在 ATTACH 操作中使用 ONLINE 关键字
- 在 DETACH 操作中使用 ONLINE 关键字
- 在 MODIFY 操作中使用 ONLINE 关键字
- CREATE INDEX 的 ONLINE 关键字
- DROP INDEX 的 ONLINE 关键字.
在辅助服务器上的 LOCK TABLE 语句行为
在高可用性集群中,您可从可更新的辅助服务器上设置表的排他锁。对于来自辅助服务器的排他模式锁请求,会话可读该表但不可更新它。此行为类似于辅助服务器上的共享访问模式;即,当一会话在给定的表上有排他锁时,其他会话不可获取那个表上的共享或排他锁。
在只读的辅助服务器上,发出 LOCK TABLE 语句的会话不锁定该表,且数据库服务器不向客户端返回错误。
集群中的共享模式锁的行为与单独服务器的相同。在成功地运行 LOCK TABLE 语句之后,用户可读该表但不可改变它,直到释放该锁为止。
对带有共享锁的表的并发访问
在成功地执行指定 IN SHARE MODE 关键字的 LOCK TABLE 语句之后,其他用户可读该表,但不可改变他的数据,直到释放该锁为止。在支持事务日志记录的数据库中,SELECT 语句可在罗列在 FROM 子句中的每一表上隐式地放置一共享锁,以便防止其他用户修改那些表,直到提交或回滚该查询为止。
对带有排他锁的表的并发访问
成功地执行带有 IN EXCLUSIVE MODE 选项的 LOCK TABLE 语句之后,其他用户不可获得对该指定表的锁。然而,当您尝试对那个表进行 DDL 操作时,如果一并发的会话(例如,通过打开游标)正在访问同一表,则您可能收到 RSAM error -106。此错误还可影响某些 DDL 语句自动地在这些表上放置的隐式的锁。
这可能是因为表锁不排除表访问。排他锁防止其他用户获得锁,但不防止那些等待释放该排他锁的写操作打开该表,或对该表的 Dirty Read 操作。您可设置 IFX_DIRTY_WAIT 环境变量来指定 DDL 等待指定的秒数,以便 Dirty Read 操作提交或回滚。
当表中的一行或多行被排他锁锁定时,对其他用户的影响部分地取决于他们的事务隔离级别。除了 Dirty Read 隔离级别之外的所有其他隔离级别中的其他用户可能遇到锁定错误,比如,由于在指定的时间限制内未释放锁,或由于发生死锁情况,导致事务失败。
在行级锁定影响一些行的表上,通过启用事务来在行级锁定的表中读取数据的最近提交的版本,可降低锁定冲突的风险,而不是等待提交或回滚在那行上持有该锁的事务。这可通过几种不同的方法实现,包括:
- 从单个事务发出此 SQL 语句
SET ISOLATION TO COMMITTED READ LAST COMMITTED;
- 对于使用 Committed Read 或 Read Committed 隔离级别的所有会话,请将 USELASTCOMMITTED 配置参数设置为 'ALL' 或 'COMMITTED READ',或者另发出带有 'ALL' 或 'COMMITTED READ' 作为会话环境选项的 SET ENVIRONMENT USELASTCOMMITTED 语句。
- 对于使用 Dirty Read 或 Read Uncommitted 隔离级别的所有会话,请将 USELASTCOMMITTED 配置参数设置为 'ALL' 或 'DIRTY READ',或者另发出带有 'ALL' 或 'DIRTY READ' 作为会话环境选项的 SET ENVIRONMENT USELASTCOMMITTED 语句。
- 对于在数据库中为其定义 user.sysdbopen( ) 过程的用户,DBA 可定义那个过程来包括 SET ENVIRONMENT USELASTCOMMITTED 语句,此语句带有 'ALL' 或 'COMMITTED READ' 作为会话环境选项,且还发出 SET ISOLATION 语句来设置 Committed Read 作为隔离级别。
- 对于在数据库中不存在为其定义 user.sysdbopen( ) 过程的用户,DBA 可定义 PUBLIC.sysdbopen 过程,该过程指定相同的 SET ENVIRONMENT USELASTCOMMITTED 和 SET ISOLATION 语句。
仅当行级锁定有效时,而不是当另一会话持有对整个表的排他锁时,此 LAST COMMITTED 隔离特性才有用。当 LOCK TABLE 应用表级锁时,此特性对于指定的表不可用。要了解更多关于此 LAST COMMITTED 特性,为了并发访问有些行被排他锁锁定的表,且为了在可支持此特性的表的种类上的限制的信息,请参阅 Committed Read 的 LAST COMMITTED 选项。