2014-09-21 76 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