gpt4 book ai didi

postgresql - 事务如何在读取数据库的上下文中工作?

转载 作者:行者123 更新时间:2023-11-29 13:24:44 25 4
gpt4 key购买 nike

我正在使用事务对 SQL 数据库进行更改。据我了解,这意味着对数据库的更改将以全有或全无的方式发生。我想知道的是,这对读取有任何保证吗?例如,假设我有一些这样的(伪)代码:

1) start TRANSACTION
2) INSERT INTO users ... // insert some data
3) count = SELECT COUNT(*) FROM ... // count something in the database
4) if count > 10: // do something based on the read
5) INSERT INTO other_table ... // write based on the read
6) COMMMIT TRANSACTION

在这段代码中,我正在执行一个INSERT,然后是一个SELECT,然后根据结果有条件地执行另一个INSERT SELECT 的。

所以我的问题是,如果另一个进程在步骤 (3) 和 (5) 之间修改数据库,count 变量和我的事务会发生什么情况?

如果有区别,我正在使用 PostgreSQL。

最佳答案

正如 Xin 指出的那样,这取决于 isolation level .

在默认的READ COMMITTED 级别,来自其他 session 的记录在提交时将变得可见;如果您根本没有启动事务,您会看到相同的记录(当然,其他进程会看到您的插入出现在不同的时间)。

使用REPEATABLE READ,您的查询将看不到事务开始后其他 session 提交的任何记录。但是,虽然您不必担心 SELECT COUNT(*) 的结果在您的交易过程中发生变化,但您不能假设这个结果在您提交时仍然是准确的。

使用 SERIALIZABLE 提供最强有力的保证:如果您的脚本在被授予对数据库的独占访问权时做正确的事情,那么它会在其他可序列化事务存在的情况下做正确的事情(或者它将彻底失败)。但是,这意味着所有可能会干扰您的事务都必须使用相同的隔离级别(这是有代价的),并且所有事务都必须准备好在序列化失败的情况下重试它们的事务。

当可序列化事务不是一个选项时,您通常通过显式锁定事物以防止并发写入来防止竞争条件。锁定记录的选择通常就足够了,但是您不能完全锁定 COUNT(*) 的结果;在你的情况下,你可能需要 lock the whole table .

关于postgresql - 事务如何在读取数据库的上下文中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35736206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com