两个进程同时在数据库中保存记录

当多个用户在数据库(MySQL,Postgres)中同时插入数据时会发生什么? 它如何优先考虑首先插入哪个记录以及后面哪个记录。 如果答案是针对程序的应用,我要求参考网络应用程序。

这绝不是完全相同的时间。 一个将在另一个之前发生。 除非你实现自己的优先级机制,否则哪一个是不确定的,你永远不应该依赖它。

至于会发生什么,这取决于。

对于同一个表的两个插入,如果数据完整性取决于它们在数据库设计中执行的顺序有一个可怕的缺陷。

对于冲突(例如,对同一记录的两次更新)。 有两种实现方式。

悲观锁定。 假设相同数据会有大量更新,因此请锁定它。 如果锁定存在失败则更新(例如,如果第一个尚未完成,则为第二个),并带有一些合适的消息。

乐观锁定。 假设很少发生碰撞。 通常这样做的方法是在记录中添加时间戳字段,以更改每次更新。 因此,当您读取数据时,您将获得时间戳,并且当您编写数据时,您只会执行此操作,如果您的时间戳与现在的时间戳匹配,并将所述时间戳更新为其中的一部分。 如果它不匹配,则执行“其他人已更改此数据消息”。

有一个妥协的位置,您尝试合并两个更新。 (例如,您更改名称,我更改地址)。 你需要真正考虑到这一点,它很混乱,并且很快变得非常复杂,并且错误运行会使数据变得混乱。

智商远远超过我的人花了很多时间在这些东西上,我个人喜欢像我一样,简单……

一般来说,两件事情不会在同一时间发生。 有一个工作队列,在某种程度上,一件事总是发生在另一件事之前。

但是,有些情况下整个交易可能需要多个步骤 – 如果这些交易中的两个几乎同时开始,它们可能会在时间上重叠。 这可能会导致问题。

例如,想象一个人在购物车中购买东西,步骤包括为他们创建订单记录以及减少和库存计数。 如果两个人几乎同时开始这个过程,他们都可能在库存减少之前购买该物品以显示物品缺货。

如果发生这样的事情,postgres(和其他现代数据库)提供了限制程序保护自己的方法。 这些包括交易锁定

对于事务 (请参阅此处的postgres文档) ,语句组作为单个单元运行 – 如果后面的一个步骤失败,则所有步骤都“回滚”。 (例如,如果由于项目现已缺货而无法减少库存,则可以回滚订单。)

使用锁定 (请参阅此处的postgres文档) ,表(甚至表中的各个行)将被锁定,以便任何其他想要访问它们的进程等待或超时。 这将阻止两个进程几乎同时更新相同的数据。

通常,绝大多数应用程序不需要这些方法中的任何一种。 除非您在某个环境中工作,例如在涉及的表包含金融交易的银行,您可能不必担心它。