RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1064951
Accepted
Ainar-G
Ainar-G
Asked:2021-01-01 04:55:19 +0000 UTC2021-01-01 04:55:19 +0000 UTC 2021-01-01 04:55:19 +0000 UTC

为什么选择...更新?

  • 772

PostgreSQL文档 说 :

Read Committed是 PostgreSQL 中的默认隔离级别。当事务使用此隔离级别时,SELECT查询(不带FOR UPDATE/SHARE子句)只能看到在查询开始之前提交的数据;它永远不会看到未提交的数据或并发事务在查询执行期间提交的更改。实际上,SELECT查询会在查询开始运行的那一刻看到数据库的快照。(……)

我以这样的方式理解它,如果我在没有明确指定隔离级别的情况下进行事务:

SELECT "id" FROM "table" WHERE /* … */

然后我会在应用程序中处理结果,然后:

UPDATE "table" SET "flag" = TRUE WHERE "id" IN (/* … */)

然后我会得到想要的结果,即更新所有具有所需 ID的行,而不管其他哪些事务在那里删除或更改。但是从有这样的事情来看 SELECT /* … */ FOR UPDATE,不是吗?

什么情况下SELECT /* … */ FOR UPDATE 需要使用?

事务隔离级别对此有何影响?你需要一个 SELECT /* … */ FOR UPDATE级别 SERIALIZABLE吗?

sql
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Мелкий
    2020-01-14T21:14:06Z2020-01-14T21:14:06Z

    只要您的交易严格按照一个接一个的进行,您就很好,没有问题。除了性能。并且为了提高性能 - 有必要允许并行执行事务。并且这里开始了一个丰富而神奇的世界concurrently control。此外,不仅在数据库中,而且在至少并行执行某些操作的任何地方。

    人们通常更了解金钱,所以让我们谈谈金钱。假设有一个用户,他的账户里有 100 钱。用户可以花掉它们,你检查余额select balance ...,然后在购买时更新余额update ... set balance = ? where ...。在一个快乐的日子里,不知怎的,这个用户的两个购买请求同时出现了。一个50块钱,第二个70块钱。其中一个必须被拒绝,因为。钱是不够的。但结果是,两次购买都通过了,你遇到了问题,你卖了一些不必要的东西。这在用户的余额中甚至是不可见的。如何?

    这是典型的race condition,两个事务首先读取数据,然后在本地做一些事情,然后再写一些事情。

    • 没有人费心去读它们,因为两笔交易都读到用户有 100 钱
    • 两笔交易自然决定有足够的钱
    • 两笔交易都更新了用户的余额

    在对资源的竞争访问中,他们只在最后一步进行战斗,稍后开始更新数据的事务首先等待第一个事务的完成。然后她老生常谈地将平衡改写为她认为正确的平衡。所谓lost update异常。

    也就是说,在目前的形式中,这两个交易被错误地序列化了。为了正确执行逻辑,第二笔传入交易必须等待第一笔交易的结果才能读取用户的余额。但是数据库并没有对此进行警告,很自然地,这第一次选择被认为没有干扰其他人。

    这只是为了警告 DBMS 我们计划对数据做一些事情,因此我们需要以不同的方式序列化事务,并且还有FOR SHARE一些FOR UPDATE补充。因此,顺便说一下,它们记录在显式锁定部分。

    • 如果在 select 中没有指定任何内容,那么,由于 MVCC 的性质,postgresql 实现将能够比以往读取数据少一点。即使现在另一个事务已经在更新这一行,我们也会得到这一行的最后一个已知的固定值。
    • 如果显式请求,那么我们可以用这个锁FOR SHARE读入许多线程而不会相互阻塞。FOR SHARE但是如果有人要更新这一行,那么他就会站在等待队列中,直到所有持有读锁的事务都完成,同时延迟所有后续FOR SHARE事务。
    • 如果请求FOR UPDATE,那么我们可以确定在我们的事务结束之前没有其他事务能够更新该行。

    也就是说,如果没有这个,从 DBMS 的角度来看,竞争事务可以在逻辑上序列化,但对于应用程序的业务逻辑来说是错误的。

    可序列化

    可序列化事务只是可重复读取事务,它为读/写冲突的危险模式添加了非阻塞监视

    Postgresql 的 Serializable 实现监视将破坏事务隔离的更改,所有受影响的事务将收到序列化错误。应用程序本身必须准备好在此隔离级别上工作,并期望随时收到序列化错误,准备好再次重试事务。

    我在这里需要它吗FOR UPDATE- 只需引用文档中有关减少可序列化隔离级别的性能下降的提示:

    由于可序列化事务自动提供的保护,消除不再需要的显式锁、SELECT FOR UPDATE 和 SELECT FOR SHARE。

    此隔离级别不需要显式锁。


    在没有明确隔离级别的事务中

    将使用设置中指定的级别default_transaction_isolation。也就是说,它可以是 Serializable 而不是 Read Committed。

    我将获得所需的结果,即更新具有所需 ID 的所有行,而不管其他哪些事务在那里删除或更改。

    您将获得与条件匹配的所有行的更新。但是否需要这个结果是关键问题。

    • 17

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5