首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL上的数据库事务一致性

PostgreSQL上的数据库事务一致性
EN

Database Administration用户
提问于 2018-11-20 17:29:52
回答 1查看 122关注 0票数 1

在一个具有三列(serial id, varchar name, varchar email)并具有两个不同事务并行执行的表中,如下所示:

交易1:

代码语言:javascript
复制
BEGIN;
INSERT INTO public.users (name, email) VALUES ('tart', 'tart@warm.com');
INSERT INTO public.users (name, email) VALUES ('tart123', 'tart123@warm123.com');
COMMIT;

Transaction2:

代码语言:javascript
复制
BEGIN;
INSERT INTO public.users (name, email) VALUES ('raspy', 'raspy@sun.com');
INSERT INTO public.users (name, email) VALUES ('raspy123', 'raspy123@sun123.com');
COMMIT;

结果是否有可能变成以下情况?

代码语言:javascript
复制
1 | tart     | tart@warm.com
2 | raspy    | raspy@sun.com
3 | tart123  | tart123@warm123.com
4 | raspy123 | raspy123@sun123.com
EN

回答 1

Database Administration用户

发布于 2018-11-20 19:11:15

serial在PostgreSQL文档中是这样定义的:

数据类型smallserialserialbigserial不是真类型,而只是创建唯一标识符列(类似于其他数据库支持的AUTO_INCREMENT属性)的一种符号方便。

他们还提出了这一警告:

由于smallserialserialbigserial是使用序列实现的,因此列中出现的值序列可能存在“漏洞”或空白,即使没有删除任何行。从序列中分配的值仍然“用完”,即使包含该值的行从未成功插入表列。例如,如果插入事务回滚,则可能发生这种情况。有关详细信息,请参阅第9.16节中的nextval()。

如果您转到nextval文档,您将得到:

将sequence对象提升到其下一个值并返回该值。这是原子性的:即使多个会话同时执行nextval,每个会话都将安全地接收一个不同的序列值。

序列是一个共享对象,在您的所有内容中。默认情况下,每个对INSERT的调用都将调用底层序列nextval,并将提供一个值,而不管刚才在事务中发生了什么。因此,值将完全取决于操作的顺序,而不是首先启动哪个事务或诸如此类的事情。

您还可以得到这个结果(取决于您的DB中其他地方同时发生了什么):

代码语言:javascript
复制
 1 | tart     | tart@warm.com
 7 | raspy    | raspy@sun.com
13 | tart123  | tart123@warm123.com
42 | raspy123 | raspy123@sun123.com

代码语言:javascript
复制
 1 | tart     | tart@warm.com
 3 | raspy    | raspy@sun.com
 2 | tart123  | tart123@warm123.com
 4 | raspy123 | raspy123@sun123.com

(这可能是你所期望的,但没有具体的保证)。

序列只是保证在两个单独的地方“永远”得到相同的值,它并不保证在增量中缺少洞或单调,特别是在多个事务中。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/223000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档