SQL如何处理多个进程将同一记录同时写入同一数据库表?

问题描述

这是我长期以来的困惑。如果多个进程将同一条记录同时写入同一数据库表中,它们是否会有冲突?

类似的问题,例如,一台主计算机不断将请求分发给其他许多计算机,例如,将一条记录插入到计算机A的表中。不知何故,此操作在机器A上非常慢,并且主控制器将向机器B重新发送完全相同的请求。那会发生什么呢?会有冲突吗?

解决方法

实际上有两个问题,但我会尝试回答主要问题。

首先,我们在谈论什么样的数据库?如果它是Oracle,PostgreSQL,MSSQL等现代RDBMS,则很可能具有逐行锁定机制,这意味着每个进程可以同时插入/更新/删除行,只要它们不相交即可。

一旦两个进程试图更新同一行,则一个进程(幸运的是第一个进程)将更新该行,而第二个进程将不得不等到第一个进程提交或回滚其事务。现在,此更新的行已被锁定,无法进行任何更改(第一个操作除外)。

如果第一个进程删除一行,也会发生同样的事情。在第一个提交或回滚事务之前,没有其他进程可以使用相同的唯一键插入新行。

现在,当我们使用两个具有相同唯一键的行插入两个进程时,这将变得更加有趣,如果让它们都完成,将破坏关系模型。表中还没有行,因此没有要锁定的内容。但是,某个地方有一个提供唯一性的索引。因此,进程不是锁定行,而是实际上将尝试锁定索引的存储桶。并且最初的过程将成功。现在,当第二个进程尝试插入行时,它将看到存储桶已锁定。像在第一种情况下一样,第二个过程将必须等到释放存储桶之后,然后检查是否可以插入并自行锁定存储桶。

这实际上是一个非常肤浅和笼统的解释,但是它给出了解决冲突机制的原理。实际的实现可能因数据库而异,并且要复杂得多。