Postgresql 如果两个进程同时修改两个事务中的数据,并且表上存在唯一约束,会发生什么情况?
我正在考虑一个生产系统中的竞争条件。数据库是PostgreSQL。应用程序是用Java编写的,但这并不相关 有一个名为“versions”的表,其中包含列“entity_ID”和“version”(以及一些其他字段)。此表包含某个实体的版本 有一个应用程序,用户可以在其中修改这些实体 对实体的每次修改都会为选项卡“versions”(使用触发器)创建一个新版本。此触发器在同一个表“versions”中查找最后一个版本,并插入具有相同实体_ID但版本=(最后一个版本+1)的新行 每4:00在PostgreSQL中运行一个夜间作业,该作业也会更改这些实体,从而更新表“versions”中的数据。这个过程的目的是在早上(在应用程序的用户开始使用它之前)完成它的工作,但不幸的是,它一直持续到白天。由于此过程在函数中运行,因此它是一个大事务。因此,它所做的更改对应用程序不可见 夜间作业使用以下工作流:Postgresql 如果两个进程同时修改两个事务中的数据,并且表上存在唯一约束,会发生什么情况?,postgresql,triggers,transactions,race-condition,unique-constraint,Postgresql,Triggers,Transactions,Race Condition,Unique Constraint,我正在考虑一个生产系统中的竞争条件。数据库是PostgreSQL。应用程序是用Java编写的,但这并不相关 有一个名为“versions”的表,其中包含列“entity_ID”和“version”(以及一些其他字段)。此表包含某个实体的版本 有一个应用程序,用户可以在其中修改这些实体 对实体的每次修改都会为选项卡“versions”(使用触发器)创建一个新版本。此触发器在同一个表“versions”中查找最后一个版本,并插入具有相同实体_ID但版本=(最后一个版本+1)的新行 每4:00在Pos
- 设置“失败的计数器”=0
- 迭代需要修改的实体
- 对BEGIN中的实体进行修改。。例外情况。。端块
- 如果出现异常,请增加“失败的\u计数器”。将异常和故障实体记录到日志表中
- 如果“计数器失败”>10,则取消工作
- 结束工作
- 何时检查唯一约束:在竞态条件步骤3或竞态条件步骤4李>
- 如果最后一个问题的答案是“竞赛条件4”,那么我如何更改系统的设计以避免上述问题李>
- 扣动扳机李>
- 添加带有时区的
时间戳类型的列
- 设置该列的默认值。大多数应用程序将使用
,但您可能需要current\u timestamp
李>clock\u timestamp()
- 在{entity_id,new timestamp column}上添加唯一约束
取消触发器可能会使您的速度大大加快。我认为您永远不会违反约束。(2) 作业修改一个锁定记录的。(3) 应用程序尝试修改,但无法获取锁,因此等待。(4) 作业提交,锁被释放。(5) 应用程序获取锁,进行更新,并创建版本X+2。对不起,我在问题中过度简化了情况。但我测试并发现,步骤(3)使应用程序在且仅在违反唯一约束的情况下等待锁定。所以你在这方面是正确的。你提出了好几点。将功能作为较小的部件运行是一种选择;然而,我认为我更愿意避免对系统进行这样的重写。用集合代替迭代也是一个很好的建议;但是,由于函数执行的操作的复杂性,这是不可行的(我简化了询问的情况)