2012-05-04 52 views
2

当多个用户完全同时在数据库(MySQL,Postgres)中插入数据时会发生什么?它如何确定首先插入哪条记录,以及哪条记录稍后插入。如果答案是特定于程序的应用程序,我在询问网络应用程序。两个进程同时在数据库中保存记录

+0

那么这是一个纯数据库问题吗?或者你指的是activerecord如何处理并发?为什么标记为Ruby? –

+0

红宝石球员回答这个问题.. –

+0

有像Ruby一样具体的战略实施,就像postgesql特定的。尽管如此,根本问题和一般解决方案是应用程序不可知的。 –

回答

4

这绝不是同一时间。一个会在另一个之前发生。 除非您实施自己的优先级排序机制,否则哪一个将是不确定的,您不应该依赖它。

至于会发生什么,以及取决于。

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

对于碰撞(例如对同一记录的两个更新)。有两种实现。

悲观锁定。假设将有相当数量的更新来处理相同的数据,因此请锁定它。如果存在锁定,则更新(例如,如果第一个未完成则为第二个)带有一些合适的消息。

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

有一个妥协的立场,你尝试并合并两个更新。 (例如你改名字,我改变地址)。您需要真正思考这个问题,但这很麻烦,并且非常快速地变得非常复杂,并且错误地运行是数据混乱的真正风险。

人们以大得多的智商比我花了很多时间在这东西,我个人喜欢把它和我一样,简单...

2

一般而言,两件事情从来没有在正好同样发生时间。有一个工作队列,在某种程度上,一件事情总是发生在另一件事之前。

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

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

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

交易(see postgres docs here),语句组作为一个单元运行 - 如果其中一个后面的步骤失败,所有步骤都会“回滚”。 (例如,如果由于商品现在缺货而不能减少库存,则可以回滚订单创建。)

随着锁定(see postgres docs here),表(或表中的甚至单个行)被锁定,使得任何其它处理想要访问他们要么等待或超时。这会阻止两个进程几乎同时更新相同的数据。

一般来说,绝大多数应用程序不需要这些方法。除非你在一个环境中工作,例如在涉及金融交易的银行,否则你可能不必担心。

相关问题