当前位置: 首页 > 知识库问答 >
问题:

Postgres等待事务完成

柯翔
2023-03-14

当在postgres中进行并发更新时,我得到一个

错误:由于并发更新,无法序列化访问

有没有办法让事务等到另一个事务完成,而不是因错误而失败?

这是我的测试案例:

-- SESSION 1
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Serializable;

SELECT pg_sleep(5); -- 5 second delay
UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';

COMMIT;

并且另一个会话(会话2)同时发生

-- SESSION 2
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Serializable;

UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';

COMMIT;

如何使事务等待上一个事务完成再执行。截至目前,它不会执行,它只会报告错误,这让我在服务器上管理故障逻辑。是否有可以使用类似事务队列的东西?或者也许是一个语句,用于检查是否有其他事务正在进行,然后等待它解决?

(注意:我使用postgres,我的事务隔离设置为可序列化)

编辑:

我做了一些小修改,解决了这个问题。我将事务隔离更改为Read-committed,并在update语句之后移动了5秒延迟。

延迟在更新语句之后很重要,因为数据库在读取更新语句之前不会在行上放置块。

下面是修改后的测试用例:

-- SESSION 1
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Read committed;

UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';
SELECT pg_sleep(5); -- 5 second delay

COMMIT;

并且另一个会话(会话2)同时发生

-- SESSION 2
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Read committed;

UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';

COMMIT;

在此方案中,会话 2 事务在提交自身之前等待会话 1 事务提交。

共有1个答案

梁丘钊
2023-03-14

您已经设置了可序列化隔离级别,这意味着一旦事务不能序列化,它就会失败。

这就是它的工作原理。

而且,不,你不能改变它的行为。

 类似资料:
  • 我正在使用Aerospike AsyncClient和Aerospike UDF模块在Aerospike 2节点集群中使用多线程插入1000万条记录。我遵循的步骤是: > 创建了一个由10个线程组成的executor服务,所有线程都将使用相同的AsyncClient 运行循环1000万次,并使用下面的代码调用execute命令 对于(int 1-0;i<10000000;i++){final in

  • 问题内容: 如何让我的代码等待,直到DispatchQueue中的任务完成?是否需要任何CompletionHandler或其他东西? 我正在使用Xcode 8.2并在Swift 3中编写。 问题答案: 使用s可以实现这一点。您可以在群组和通话达到平衡时得到通知: 或者您可以等待: 注意 :阻止当前队列(在您的情况下可能是主队列),因此您必须在另一个队列上(如上面的示例代码中)以避免 死锁 。

  • 我有4个按钮,基本上他们设置一个变量的值,当一个国际象棋提升需要做。然而,我认为程序流并没有等待用户做出那个选择。我的代码是这样的: 此时,当窗口显示时,当用户没有选择值时,程序继续运行,而另一个函数使用了导致错误的。有没有什么方法可以让我停止程序流,直到用户点击其中一个按钮,以便后面的代码可以使用该变量的值?

  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 我正在运行这样的多个服务:(例如,在多个线程中读取文件) 是一个扩展类的类,它正在做一些事情,比如读取文件。它是从另一个线程调用的,该线程不是JavaFX应用程序线程。 我如何等到所有这些服务完成后再调用? 可复制的例子:

  • 问题内容: 我有一个登录框架,我必须从另一个线程等待。成功登录后,框架将自行处置。我想弹出该应用程序的主框架。现在,我正在观看一个布尔值,以确定何时启动主机。正确的做法是什么?观看布尔值只是感觉并不优雅。 问题答案: 如果您有Java 5或更高版本,则可以使用CountDownLatch。例如,假设主框架最初处于控制状态,则让主框架创建一个倒数为1的,然后将此锁存器传递给登录框架。然后让主机等待锁