首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgres、MVCC和锁定

Postgres、MVCC和锁定
EN

Database Administration用户
提问于 2011-04-11 22:22:52
回答 3查看 2.9K关注 0票数 9

我有一系列SQL语句,如下所示:

代码语言:javascript
复制
BEGIN;
SELECT counter FROM table WHERE id=X FOR UPDATE;
REALLY COMPLEX QUERY;
UPDATE table SET counter=Y WHERE id=X;
END;

我想在重新计算计数器值时阻止它被读取,但是根据Postgres文档,“行级锁不会影响数据查询;它们只阻止写入器到同一行。”

问题:

  1. 如果“外排”行锁不阻止读取,它有什么意义?这仅仅是为了防止其他事务获取共享锁吗?
  2. 如果我用SELECT读取行..。对于分享,这是否达到了与“外排”锁相同的影响?
  3. 是否可以关闭表/架构/数据库的MVCC并允许就地写入?
EN

回答 3

Database Administration用户

发布于 2011-04-12 14:21:18

到1)任何其他会话都将读取由事务修改的数据,就像在“开始”语句之前一样,只要您的事务没有提交。一旦您的事务提交,它将读取计数器的新值。关键是,其他人不必等待,而且总是会看到一致的数据库。

你为什么不试一试“独家访问”呢?(见http://www.postgresql.org/docs/current/static/explicit-locking.html)

编辑:如果不喜欢用“访问独占”锁锁定整个表,也可以使用“咨询锁”(参见上面链接中的13.3.4节)。

票数 6
EN

Database Administration用户

发布于 2011-04-16 17:52:46

如果要阻止的读取同时执行同一事务,只需使用不同的数据,请使用UPDATE语句和reads子句。

查看UPDATE语句上的文档。要回答关于独占行锁的点的问题,这是为了防止数据不一致的同时更新。读者在任何时候都能获得数据库的一致视图。

票数 1
EN

Database Administration用户

发布于 2011-11-21 21:58:45

在您提供的代码示例中,对该行的所有读取都将看到旧值,直到事务提交为止。

1)假设代码示例以相同的X值同时运行两次。如果实例A已经运行了select ... for update,那么它已经锁定了该行,直到提交为止。执行相同操作的实例B将阻止试图以相同方式获取锁。只有当A提交时,B才能继续。然后,B将得到A在其最后更新中留下的值。

如果Y取决于select ... for update查询读取的值,或者“复杂”部分中的另一个读取值,那么这将产生与连续运行相同的效果--您不会得到其中一个结果将被丢弃的争用条件。

如果Y纯粹是中间复杂查询的结果,那么在没有select ... for update的情况下并行运行它,它们将进行相同的更新。

2) for share将允许该行上的其他选择继续进行,但将导致任何试图阻止select ... for updateupdate ...的操作,直到完成为止。如果示例代码同时运行两次,它们将在到达update语句时陷入死锁,导致其中一条被中止。

( 3)不。这样做是危险的,因为读者可以阅读一个半更新的字段。(或阅读开始后更新的字段的其余部分。)它还可能破坏一致性,向读者显示在其事务开始后更新的值。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/2154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档