在PostgreSQL数据库事务处理未知的状态

背景

数据库的事务是一个原子操作,无论是成功还是失败,但实际上,从客户端的角度来看,可能有第三种状态:未知状态。

当用户提交该事务结束(提交,回滚,准备pxact XACT,回滚,犯pxact)的请求,接收请求的数据库,数据库可能会失败,也可能成功执行,不管如何写日志的沃尔玛,堵塞,则数据库将执行结果返回给客户端的ACK。

这里有几种可能性,导致客户不知道到底发生了什么

在接收到客户机请求之后,数据库不会返回任何对客户机的ACK。客户对请求感到非常困惑。它只能处于未知状态的人类数据库中。

处理未知事务

未知事务是客户机没有接收到提交回滚ACK的事务。不知道它是成功还是失败。

多个节点(基于仲裁的同步复制)和单个节点可能有未知的事务,它们的影响和形式是一致的。

你如何处理未知的事务

未知事务分为以下情况。

回滚,提交,准备pxact XACT,回滚,在一些未知的处理方法进行pxact例:

1、二阶段未知状态问题的求解

在准备阶段,未知的,切换后的领导者,客户验收准备XACT的状态通过pg_prepared_xacts观。如果没有准备XACT,提示失败。然后整个交易重新启动。如果准备XACT的存在,表明准备XACT是成功的。

提交或回滚准备XACT相位未知,开关检查准备该状态切换后,重新提交或回滚的准备。不存在表明它是成功的(我们认为2PC是一定成功),不需要处理。

2、非两阶段交易,回滚未知不需要处理,回滚失败或成功的客户是相同的结果,因为它会滚回来,这是数据库的原子性的保证。

3,非二相事务,提交未知处理,非常严格的场景,程序可以设计事务状态可以是可追踪的,例如:

开始的交易记录交易编号或序列号,交易号是数据库中唯一的水,根据交易号查询它的状态,如PostgreSQL。

但并不是所有的数据库都有这个接口,比如非物理流数据库复制,您可以在全局事务中增加事务,只查看事务是否提交事务。它利用事务的原子特性,要么完全成功,要么完全失败。

一个使用业务流水线的事务状态判断示例。

开始;

要生成唯一的业务流ID,写入到一个地下水位,并记录在程序或其他数据库中的序列号,以供参考。

交易执行

提交交易;



-未知的出现



通过唯一的业务流水线ID查询此记录是否存在于数据库中。

如果不存在,事务提交失败。

如果存在,事务将成功提交。(因为数据库的事务是原子操作)