2014-09-21 73 views
0

假设我在PostgreSQL中有以下存储过程。 (请注意,这不是真正的代码。我知道这可以用另一种更好的方式来完成,这只是一个例子来说明我的问题)PostgreSQL函数是原子吗? (ID生成)

​​

比方说,两个不同的用户运行这个几乎在同时。他们可以得到相同的身份证件吗?换句话说,我会尝试解释一下。在代码中,我评论了两条语句。如果两个用户同时运行它。声明以什么顺序调用。我可以肯定这将是这样的:

  • 用户声明1
  • 用户声明2
  • 用户B声明1
  • 用户B声明2

或可能是像这样(导致相同的ID):

  • 用户A声明1
  • 用户B声明1
  • 用户声明2
  • 用户B声明2

我希望你明白我的问题。我真的试图寻找网络的答案,但没有运气。这可能是因为我没有任何名字?这叫什么?

非常感谢您的帮助。

回答

3

让我们假设两个不同的用户几乎同时运行它。他们可以得到相同的身份证件吗?

是的,当然。这与将它作为事务外的两个单独语句运行相同,并在应用中添加。

I wrote about this recently

使用SEQUENCE确保唯一的ID。伪类型使得这更容易。请注意,ID不能保证无缝;有正常的ID有:1,3,4,5,6,9,10,11,14 ......如果事务回滚,服务器重启等。

如果这对您来说是个问题,你会想要做的是:

SELECT CurrentID INTO iNewID FROM TestTable FOR UPDATE; 
... blah blah ... 

...这将锁定该行,以便其他事务无法更新它,直到当前提交或回滚。

UPDATE TestTable 
    SET CurrentID = iNewID 
    RETURNING CurrentID; 

然后你就可以在SQL函数或包裹在PL/PGSQL与RETURN QUERY运行:可实际使用PostgreSQL相关功能集成到简化。

+0

非常感谢您的回答,并链接到伟大的文章!我只是使用ID示例来说明我的问题。这不是我在实际工作中试图做的事情。对于我的真实工作,无法编辑SQL或使用“FOR UPDATE”。也许我必须查看文章中提到的SERIALIZABLE事务。但我不喜欢的是第二次会议被中止。存储过程是否不可能像单条语句一样工作?因此,如果两个会话同时启动,其中一个会等待另一个完成,然后运行? – Thomas 2014-09-21 18:26:29