PostgreSQL函数是原子函数吗?(身份证生成)

PostgreSQL函数是原子函数吗?(身份证生成),postgresql,sequence,auto-increment,Postgresql,Sequence,Auto Increment,假设我在PostgreSQL中有以下存储过程。(请注意,这不是真正的代码。我知道这可以用另一种更好的方式来完成,这只是一个例子来说明我的问题) 假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗 我将试着用其他的话来解释。在代码中,我对两条语句进行了注释。如果两个用户同时运行此操作。语句的调用顺序是什么。我能肯定会是这样吗: 用户A声明1 用户A声明2 用户B报表1 用户B报表2 或者可能是这样(导致相同的ID): 用户A声明1 用户B报表1 用户A声明2 用户B报表2 我希

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

假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗

我将试着用其他的话来解释。在代码中,我对两条语句进行了注释。如果两个用户同时运行此操作。语句的调用顺序是什么。我能肯定会是这样吗:

  • 用户A声明1
  • 用户A声明2
  • 用户B报表1
  • 用户B报表2
或者可能是这样(导致相同的ID):

  • 用户A声明1
  • 用户B报表1
  • 用户A声明2
  • 用户B报表2
我希望你能理解我的问题。我真的试着在网上搜索这个问题的答案,但没有成功。这可能是因为我没有这个名字?它叫什么

非常感谢你的帮助

假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗

当然可以。这就像你在一个事务之外以两个独立的语句运行它,在你的应用程序中进行加法一样

使用密码确保ID的唯一性。伪类型使这更容易。注意,不能保证ID是无间隙的;有像这样的ID是正常的:1,3,4,5,6,9,10,11,14。。如果事务回滚,服务器将重新启动,等等

如果这对您来说是一个问题,您可以改为:

SELECT CurrentID INTO iNewID FROM TestTable FOR UPDATE;
... blah blah ...
。。。这将锁定该行,以便在当前事务提交或回滚之前,其他事务无法更新该行。使用PostgreSQL的特定功能可以将其简化为:

  UPDATE TestTable
  SET CurrentID = iNewID
  RETURNING CurrentID;
然后,您可以将其封装在SQL函数中,或使用返回查询在PL/PgSQL中运行

假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗

当然可以。这就像你在一个事务之外以两个独立的语句运行它,在你的应用程序中进行加法一样

使用密码确保ID的唯一性。伪类型使这更容易。注意,不能保证ID是无间隙的;有像这样的ID是正常的:1,3,4,5,6,9,10,11,14。。如果事务回滚,服务器将重新启动,等等

如果这对您来说是一个问题,您可以改为:

SELECT CurrentID INTO iNewID FROM TestTable FOR UPDATE;
... blah blah ...
。。。这将锁定该行,以便在当前事务提交或回滚之前,其他事务无法更新该行。使用PostgreSQL的特定功能可以将其简化为:

  UPDATE TestTable
  SET CurrentID = iNewID
  RETURNING CurrentID;
然后,您可以将其封装在SQL函数中,或使用返回查询在PL/PgSQL中运行

假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗

当然可以。这就像你在一个事务之外以两个独立的语句运行它,在你的应用程序中进行加法一样

使用密码确保ID的唯一性。伪类型使这更容易。注意,不能保证ID是无间隙的;有像这样的ID是正常的:1,3,4,5,6,9,10,11,14。。如果事务回滚,服务器将重新启动,等等

如果这对您来说是一个问题,您可以改为:

SELECT CurrentID INTO iNewID FROM TestTable FOR UPDATE;
... blah blah ...
。。。这将锁定该行,以便在当前事务提交或回滚之前,其他事务无法更新该行。使用PostgreSQL的特定功能可以将其简化为:

  UPDATE TestTable
  SET CurrentID = iNewID
  RETURNING CurrentID;
然后,您可以将其封装在SQL函数中,或使用返回查询在PL/PgSQL中运行

假设两个不同的用户几乎同时运行此功能。他们能得到相同的身份证吗

当然可以。这就像你在一个事务之外以两个独立的语句运行它,在你的应用程序中进行加法一样

使用密码确保ID的唯一性。伪类型使这更容易。注意,不能保证ID是无间隙的;有像这样的ID是正常的:1,3,4,5,6,9,10,11,14。。如果事务回滚,服务器将重新启动,等等

如果这对您来说是一个问题,您可以改为:

SELECT CurrentID INTO iNewID FROM TestTable FOR UPDATE;
... blah blah ...
。。。这将锁定该行,以便在当前事务提交或回滚之前,其他事务无法更新该行。使用PostgreSQL的特定功能可以将其简化为:

  UPDATE TestTable
  SET CurrentID = iNewID
  RETURNING CurrentID;

然后,您可以将其封装在SQL函数中,或使用返回查询在PL/PgSQL中运行

,非常感谢您的回答和到伟大文章的链接!。。。我只是用ID示例来说明我的问题。这不是我在实际工作中试图做的。对于我的实际工作,不可能编辑SQL或使用“For UPDATE”。也许我必须研究一下你文章中提到的可序列化事务。但我不喜欢的是第二次会议被中止了。存储过程不可能以与单个语句相同的方式工作。所以,如果两个会话同时开始,其中一个等待另一个完成,然后运行?非常感谢您的回答和链接到伟大的文章!。。。我只是用ID示例来说明我的问题。这不是我在实际工作中试图做的。对于我的实际工作,不可能编辑SQL或使用“For UPDATE”。也许我必须研究一下你文章中提到的可序列化事务。但我不喜欢的是第二次会议被中止了。存储过程不可能以与单个语句相同的方式工作。所以,如果两个会话同时开始,其中一个等待另一个完成,然后运行?非常感谢您的回答和链接到伟大的文章!。。。我只是用ID示例来说明我的问题。这不是我在实际工作中试图做的。对于我的实际工作,不可能编辑SQL或使用“For UPDATE”。也许我必须研究一下ar中提到的可序列化事务