3

当多个用户同时在数据库(MySQL、Postgres)中插入数据时会发生什么?它如何确定先插入哪条记录和稍后插入哪条记录的优先级。如果答案是特定于程序的应用程序,我是在参考网络应用程序时询问的。

4

2 回答 2

5

一般来说,两件事永远不会同时发生。有一系列工作,在某种程度上,一件事总是先于另一件事发生。

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

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

在可能发生此类事情的情况下,postgres(和其他现代数据库)提供了限制程序以保护自己的方法。这些包括事务锁定

使用事务 (请参阅此处的 postgres 文档),语句组作为一个单元运行——如果后面的步骤之一失败,所有步骤都将“回滚”。(例如,如果由于商品现在缺货而无法减少库存,则可以回滚订单创建。)

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

In general, the vast majority of applications don't require either of these approaches. Unless you're working in an environment such as at a bank where the tables involved contain financial transactions, you probably won't have to worry about it.

于 2012-05-04T11:56:00.757 回答
4

从来都不是完全相同的时间。一个会在另一个之前发生。除非您实施自己的优先级机制,否则哪个会是不确定的,您永远不应该依赖它。

至于会发生什么,那要看情况了。

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

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

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

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

有一个妥协的立场,你尝试合并两个更新。(例如你改名,我改地址)。不过,您需要真正考虑一下,它很混乱,并且很快就会变得非常复杂,并且运行错误会造成数据混乱的真正风险。

智商比我高得多的人在这些东西上花了很多时间,我个人喜欢像我一样保持它,简单......

于 2012-05-04T10:48:27.520 回答