繁体   English   中英

如果两个流程同时修改两个事务中的数据并且在表上存在唯一约束,将会发生什么?

[英]What will happen if two processes modify data in two transactions at the same time and there is a unique constraint on the table?

我正在考虑正在研究的生产系统中的竞争状况。 数据库是PostgreSQL。 应用程序是用Java编写的,但这无关紧要。

有一个名为“版本”的表,其中包含列“ entity_ID”和“版本”(以及其他一些字段)。 该表包含某个实体的版本。

用户可以在其中修改这些实体的应用程序。

实体的每次修改都会为表格“版本”创建一个新版本(使用触发器)。 此触发器在同一表“版本”中找到最新版本,并插入具有相同entity_ID的新行,但version =(最新版本+ 1)。

在PostgreSQL中每4:00运行一次夜间工作,该工作也会更改这些实体,因此会更新表“版本”中的数据。 该过程旨在在早上(在应用程序的用户开始使用它之前)完成其工作,但是不幸的是直到一天。 由于此过程在函数中运行,因此这是一项大事务。 因此,它所做的更改对于应用程序是不可见的。

每晚工作使用以下工作流程

  • 设置“ failed_counter” = 0
  • 遍历需要修改的实体
  • 对BEGIN .. EXCEPTION .. END块内的实体进行修改
  • 如果存在例外,请增加“ failed_counter”。 将异常和失败的实体记录到日志表中。
  • 如果“ failed_counter”> 10,则取消工作。
  • 结束工作

这导致以下竞争条件发生了几次(假设X是实体A的最新版本):

  1. 每晚开始工作
  2. 夜间作业修改实体A,创建版本X + 1
  3. 应用程序还用于修改实体A,还创建了版本X + 1(因为夜间作业事务尚未提交,因此应用程序看不到版本X + 1)
  4. 夜间工作结束,导致提交
  5. 现在有两个版本,版本号为X + 1,这会导致应用程序中断。

我以为我可以通过在字段(entity_ID,版本)上使用UNIQUE CONSTRAINT来解决问题。 我认为这将导致应用程序在竞争条件步骤3中收到错误(由于违反了UNIQUE CONSTRAINT)。但是我不确定唯一约束在这种情况下如何工作。 在竞争条件步骤3中,当应用程序添加版本时,数据库是否检查UNIQUE CONSTRAINT? 我想没有,因为每晚处理的事务尚未完成。 如果我是正确的,并且仅在竞赛条件第4步中检查了UNIQUE CONSTRAINT,则在进行COMMIT时,这将导致整个夜间过程失败,这是不希望的结果。

因此,问题如下。

  • 什么时候检查UNIQUE CONSTRAINT:在竞赛条件第3步或竞赛条件第4步?
  • 如果最后一个问题的答案是“竞赛条件4”,那么我如何才能更改系统设计以避免上述问题?

默认情况下,在每个语句的末尾检查PostgreSQL中的唯一约束。 使用psql测试行为很容易。

一些大的红旗。

由于此过程在函数中运行,因此这是一项大事务。

这不是一个大事务,因为您正在运行一个函数。 这是一笔很大的交易,因为您没有多次对较小的数据子集运行函数。 是否可以对子集运行功能取决于应用程序。

遍历需要修改的实体

SQL数据库的粗略经验法则:迭代总是一个错误。

SQL是一种面向集合的语言。 处理集合通常比迭代快,通常要快几个数量级。

如果“ failed_counter”> 10,则取消工作。

这看起来很可疑。 为什么九个失败还可以? 为什么任何故障好吗?

我以为我可以通过在字段(entity_ID,版本)上使用UNIQUE CONSTRAINT来解决问题。

那你还没有对这些两列的唯一约束是一个很大的,挥舞着红旗。 首先解决此问题。

应用程序显然应该在等待批处理作业完成,而不是在等待,这一事实可能是也可能不是系统设计问题。 (闻起来像是系统设计问题。)

在PostgreSQL中每4:00运行一次夜间工作...

您是否考虑从3:00开始?

对此进行测试,但不要在生产服务器上进行测试。

  • 放下扳机。
  • 添加timestamp with time zone类型的列。
  • 设置该列的默认值。 大多数应用程序将使用current_timestamp ,但是您可能需要使用clock_timestamp() 文件
  • 在{entity_id,新的时间戳列}上添加唯一约束。

消除触发器可能会为您带来足够的速度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM