[英]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运行一次夜间工作,该工作也会更改这些实体,因此会更新表“版本”中的数据。 该过程旨在在早上(在应用程序的用户开始使用它之前)完成其工作,但是不幸的是直到一天。 由于此过程在函数中运行,因此这是一项大事务。 因此,它所做的更改对于应用程序是不可见的。
每晚工作使用以下工作流程 :
这导致以下竞争条件发生了几次(假设X是实体A的最新版本):
我以为我可以通过在字段(entity_ID,版本)上使用UNIQUE CONSTRAINT来解决问题。 我认为这将导致应用程序在竞争条件步骤3中收到错误(由于违反了UNIQUE CONSTRAINT)。但是我不确定唯一约束在这种情况下如何工作。 在竞争条件步骤3中,当应用程序添加版本时,数据库是否检查UNIQUE CONSTRAINT? 我想没有,因为每晚处理的事务尚未完成。 如果我是正确的,并且仅在竞赛条件第4步中检查了UNIQUE CONSTRAINT,则在进行COMMIT时,这将导致整个夜间过程失败,这是不希望的结果。
因此,问题如下。
默认情况下,在每个语句的末尾检查PostgreSQL中的唯一约束。 使用psql测试行为很容易。
一些大的红旗。 。 。
由于此过程在函数中运行,因此这是一项大事务。
这不是一个大事务,因为您正在运行一个函数。 这是一笔很大的交易,因为您没有多次对较小的数据子集运行函数。 是否可以对子集运行功能取决于应用程序。
遍历需要修改的实体
SQL数据库的粗略经验法则:迭代总是一个错误。
SQL是一种面向集合的语言。 处理集合通常比迭代快,通常要快几个数量级。
如果“ failed_counter”> 10,则取消工作。
这看起来很可疑。 为什么九个失败还可以? 为什么任何故障好吗?
我以为我可以通过在字段(entity_ID,版本)上使用UNIQUE CONSTRAINT来解决问题。
那你还没有对这些两列的唯一约束是一个很大的,挥舞着红旗。 首先解决此问题。
应用程序显然应该在等待批处理作业完成,而不是在等待,这一事实可能是也可能不是系统设计问题。 (闻起来像是系统设计问题。)
在PostgreSQL中每4:00运行一次夜间工作...
您是否考虑从3:00开始?
对此进行测试,但不要在生产服务器上进行测试。
timestamp with time zone
类型的列。 current_timestamp
,但是您可能需要使用clock_timestamp()
。 文件 消除触发器可能会为您带来足够的速度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.