当用户在事务完成之前关闭浏览器选项卡/窗口时,数据库会话会发生什么情况



例如,在网店场景中,用户继续按购物车上的"购买",如果他关闭浏览器窗口或向下选项卡会发生什么?

例如,更新相关产品数量的数据库事务或触发的数据库触发器作为响应并记录事务的详细信息是回滚还是继续完成?

换句话说,一个"系统"是否能够确定用户是自愿还是意外地关闭了他的浏览器,比如断电或互联网连接中断,并终止或取消他的交易作为回应?

在现实世界环境中,事物是如何运作的?

在这种情况下可以观察到的行为不仅取决于数据库,还取决于 Web 应用程序及其后备服务的体系结构。

在评估此类情况时,重要的是要考虑多个部分 - 通常在浏览器中使用Web应用程序的购物者和备份数据库之间至少有一个(通常是两个或更多)层。

如果我们从最简单的情况开始(假设没有 Web 应用程序并且购物者直接连接到数据库),答案是肯定的。 Oracle 的内部监视器和负责连接和断开连接的驱动程序非常擅长检测客户端何时因未提交的更改断开连接并回滚内容。 这是任何数据库服务器中的重要功能,因为许多客户端可能需要在短时间内更新相同的数据(例如在零售环境中购买商品),并且任何类型的数据丢失、无望、永久锁定都会严重破坏数据库提供并发数据访问的能力。 我将在下面举一个例子来说明这一点,但是有大量的相关文档。 概念手册中的流程有很多很好的相关信息。

假装我们没有网络应用程序,只是通过 sql plus 等进行连接。 我们可以看到这种检测的实际效果。

让我们创建一个测试表:

CREATE TABLE PRODUCT(PRODUCT_ID NUMBER,QUANTITY_REMAINING NUMBER);
Table created.

并给它一些记录:

INSERT INTO PRODUCT VALUES (1,100);
INSERT INTO PRODUCT VALUES (2,1);
COMMIT;
1 row created.
1 row created.
Commit complete.

现在让我们让两个会话由不同的用户启动。 这两个会话都想购买项目 1。Session A先到达那里。

Session A

UPDATE PRODUCT
SET QUANTITY_REMAINING = QUANTITY_REMAINING - 1
WHERE PRODUCT_ID = 1; 
1 row updated.

然后,在Session A意外退出之前,Session B也尝试购买产品 1。 她必须等到 A 会话完成。

Session B

UPDATE PRODUCT
SET QUANTITY_REMAINING = QUANTITY_REMAINING - 1
WHERE PRODUCT_ID = 1; 

注意这里没有"1 row updated."。
现在我将远程杀死Session A(在本例中为 pid 8771)它没有机会提交或回滚,或正常退出、断开连接等。

% kill -9 8771 
zsh: killed     sqlplus /nolog

现在Session A消失了,但如果我们看一下会话 B,我们可以看到它立即能够继续:

1 row updated.

所以是的,Oracle 进程监控可以处理异常的客户端断开连接,就像正常的客户端断开连接和回滚一样。

但这只是故事的一小部分...在典型的 Web 应用程序中,由 Web 容器管理的连接池中存在(至少一个)非常长期的连接。 对于数据库,连接的客户端是单个用户还是大型 Web 应用程序并不重要,它处理意外断开连接的方式相同。

但在 Web 应用程序中,用户无法控制 Web 应用程序的数据库连接 - 用户通过其浏览器与 Web 应用程序交互,而浏览器可能会反过来对与数据库通信的另一个服务应用程序进行其他调用。 浏览器中的用户不知道正在更新哪些数据或如何更新,只是他们想将某些东西放入购物车。 他们无法控制 Web 应用程序对其数据库连接执行的操作。

有了这些额外的部分,答案取决于应用程序体系结构和设计(而不是数据库)。 通常,如果用户发送了将某些东西放入购物车(或完成订单)的请求,然后在获得响应之前意外断开连接,则他们的请求仍将由服务器完成,但他们只是不会在那里获得"确定"响应。

然后,应用程序开发人员(或Web框架)将决定如何处理购物车内商品(已成功保存到数据库),该商品可能无限期地等待失踪的购物者。

许多应用程序开发人员(和 Web 框架)内置措施,以帮助客户清楚地了解其请求的状态(例如,阻止选项卡或浏览器退出的弹出窗口,其中包含"您确定要丢失未完成的订单吗?"等)。 或者会内置监视器来"回滚"购物车中但在一段时间后未实际购买的东西,或者会发送电子邮件以确认购买何时实际完成(如果单击"购买"后刚停电)等。 但这由应用程序开发人员决定。

总而言之,是的,Oracle 数据库可以在客户端断电等情况下检测不完整的事务并很好地回滚。 对于Web应用程序,有不同的设计和技术在发挥作用,以满足在不同时间失踪的客户的不同需求,并提供可理解和令人满意的用户体验。

最新更新