分享
 
 
 

PostgreSQL学习手册之明确锁定

王朝mssql·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

9.3. 明确锁定

PostgreSQL 提供了各种各样的锁模式用于 控制对表中的数据的并发访问。这些模式可以用于在 MVCC 无法给出期望的行为的时候用于应用控制的锁定。同样,大多数 PostgreSQL 命令自动施加恰当的锁以保证 被引用的表在命令执行的时候不会以一种不兼容的方式被删除或者修改。 (比如,在存在其它并发操作的时候,ALTER TABLE 是 不能在同一个表上面执行的。)

9.3.1. 表级锁

PostgreSQL 提供多种锁模式来控制对表中数据的并行访问。 用户通常不需要关心不同的锁模式,因为 PostgreSQL 命令自动获取恰当的锁模式以 确保在保持数据完整的同时提供一定的并发访问. 不过,用户可以使用 LOCK TABLE 命令用任何可以获取的模式手工地锁住表.

下面的列表显示了可用的锁模式和它们被 PostgreSQL 自动使用的环境. 请注意所有这些锁模式都是表级锁,即使它们的名字包含单词 "row".这些锁模式的名称是历史造成的. 从某种角度而言,这些名字反应了每种锁模式的典型用法 --- 但是语义都是一样的。 两种锁模式之间真正的区别是它们有着不同的冲突锁集合。两个事务在同一时刻不能 在同一个表上持有相互冲突的锁。(不过,一个事务决不会和自身冲突 --- 比如, 它可以在一个表上请求 ACCESS EXCLUSIVE 然后稍后的时候请求 ACCESS SHARE。)非冲突锁模式可以由许多事务并发地持有。 请特别注意有些锁模式是自冲突地(比如,ACCESS EXCLUSIVE 模式就不能够同时被多个事务拥有)而其它地都不是自冲突地(比如, ACCESS SHARE 可以被多个事务持有)。一旦请求到了某种锁, 那么该锁模式将持续到事务结束。

要检查在一个数据库服务器里当前正使用地锁,我们可以使用 系统视图 pg_locks。有关监控锁管理器子系统的 更多信息,请参考 PostgreSQL 7.3 管理员手册。

表级锁模式

ACCESS SHARE

只与 ACCESS EXCLUSIVE 冲突。

SELECT 命令在被引用的表上请求一个这种锁。 通常,任何只读取表而不修改它的命令都请求这种锁模式。

ROW SHARE

与EXCLUSIVE和ACCESS EXCLUSIVE 模式冲突。

SELECT FOR UPDATE 命令在目标表上需要一个这样模式的锁(加上在所有被引用但没有 FOR UPDATE 的表上的 ACCESS SHARE 锁)。

ROW EXCLUSIVE

与 SHARE,SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。

命令 UPDATE,DELETE, 和 INSERT 自动请求这个锁模式. (加上所有其它被引用的表上的 ACCESS SHARE 锁)。 通常,这种锁将被任何修改表重数据的查询请求。

SHARE UPDATE EXCLUSIVE

和 SHARE UPDATE EXCLUSIVE,SHARE, SHARE ROW EXCLUSIVE,EXCLUSIVE, 和 ACCESS EXCLUSIVE 模式冲突. 这个模式保护一个表不被并发模式改变和 VACUUM。

VACUUM(不带 FULL 选项) 请求这样的锁.

SHARE

与 ROW EXCLUSIVE,SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE,EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。 这个模式避免表的并发数据修改。

CREATE INDEX 语句要求这样的锁模式。

SHARE ROW EXCLUSIVE

与 ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE,SHARE, SHARE ROW EXCLUSIVE,EXCLUSIVE, 和 ACCESS EXCLUSIVE 模式冲突。

任何命令都不会自动请求这样的锁模式.

EXCLUSIVE LOCK

与 ROW SHARE,ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE,SHARE ROW EXCLUSIVE, EXCLUSIVE 和 ACCESS EXCLUSIVE 模式冲突。 这个模式只允许并发 ACCESS SHARE,也就是说, 只有对表的读动作可以和持有这个锁模式的事务并行执行。

任何命令都不会自动请求这样的锁模式.

ACCESS EXCLUSIVE

与所有模式冲突. ( ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, 和 ACCESS EXCLUSIVE). 这个模式保证其所有者(事务)是可以用任意方式访问该表的唯一事务。

ALTER TABLE, DROP TABLE,和 VACUUM FULL 命令要求这样的锁. 在 LOCK TABLE 命令没有明确声明需要的锁模式时, 它也是缺省模式.

注意: 只有 ACCESS EXCLUSIVE 阻塞 SELECT (没有 FOR UPDATE语句)。

9.3.2. 行级锁

除了表级锁以外,还有行级锁.特定行上的行级锁是在行被更新的时候自动请求的 (或者被删除时或标记为更新).锁一致保持到事务提交或者回滚。 行级锁不影响对数据的查询; 它们只阻塞对同一行的写入. 要在不修改某行的前提下请求在该行的行级锁,用 SELECT FOR UPDATE 选取该行。请注意一旦我们请求了特定的行级锁, 那么该事务就可以多次对该行进行更新而不用担心冲突。

PostgreSQL 不会在内存里保存任何关于已修改行的信息,因此对一次锁定的行数没有 限制.不过,锁住一行会导致一次磁盘写;因此,象 SELECT FOR UPDATE 将修改选中的行以标记它们, 因此会导致磁盘写.

除了表级别的和行级别的锁以外,页面级别的共享/排他销也用于控制对共享缓冲池中 表页面的读/写访问。这些锁在抓取或者更新一条记录后马上被释放。 应用程序员通常不需要关系页级锁,我们在这里提到它们只是为了 完整.

9.3.3. 死锁

明确锁定的使用可能会增加死锁的可能性, 死锁是是指两个(或多个)事务相互持有对方期待的锁。比如, 如果事务 1 在表A上持有一个排他锁,同时试图请求一个在表B 上的排他锁,而事务 2 已经持有表B的排他锁,而却正在请求 在表A上的一个排他锁,那么两个事务就都不能执行。 PostgreSQL 自动侦测到死锁条件 并且会通过退出一个当事的事务来解决这个问题,以此来允许其它 事务完成。(具体哪个事务会被退出是很难预计的,而且也不应该 依靠这样的预计。)

要注意的是死锁也可能会因为行级锁而发生(因此,即使是没有使用 明确的锁定,也可能发生)。考虑这样一种情况,两个并发事务在修改 一个表。第一个事务执行了:

UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;

这样就在指定帐号的行上请求了一个行级锁。然后,第二个事务执行:

UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;

UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;

第一个 UPDATE 语句成功地在指定行上请求到了 一个行级锁,因此它成功更新了该行。但是第二个 UPDATE 语句发现它试图更新地行已经被锁住了,因此它等待持有该锁地事务 结束。事务二现在就在等待事务一结束,然后再继续执行。现在,事务一 执行:

UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;

事务一企图在指定行上请求一个行级锁,但是它得不到:事务二已经 持有这样的锁了。所以它等待事务二完成。因此,事务一在事务二上 阻塞住了,而事务二在事务一上阻塞住了:这就是一个死锁条件。 PostgreSQL 将侦测这样的条件并 退出其中一个事务。

防止死锁的最好方法通常是保证所有使用一个数据库的应用都以 一致的顺序在多个对象上请求锁定。这也是前面的死锁例子的死锁 原因:如果两个事务以同样的顺序更新那些行,那么就不会发生死锁。 我们也要保证在一个对象上请求的第一个锁是该对象需要的最高的 锁模式。如果我们无法提前核实这些问题,那么我们可以通过 在现场重新尝试因死锁而退出的事务的方法来处理。

只要没有检测到死锁条件,一个等待表级锁或者行级锁的事务将 等待冲突锁的释放不确定的时间。这就意味着一个应用持有打开的事务 时间太长可不是什么好事情(比如锁,等待用户输入)。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有