PostgreSQL 9.2.1 中具有可序列化隔离的谓词锁定

2024-01-08

我已经仔细阅读了关于事务隔离的 postgres 文档 http://www.postgresql.org/docs/current/static/transaction-iso.html建议在我的其他问题 https://stackoverflow.com/questions/12824217/isolation-level-serializable-in-spring-jdbc但我还没有设法理解“谓词锁定”的东西。

我希望有人能启发我:-)

根据文档:与大多数其他数据库系统一样,PostgreSQL 中的谓词锁基于事务实际访问的数据

听起来不错,那么为什么会发生以下情况呢?

CREATE TABLE mycustomer(cid integer PRIMARY KEY, licenses integer);
CREATE TABLE mydevice(id integer PRIMARY KEY, cid integer REFERENCES 
mycustomer (cid), status varchar(10));

INSERT INTO mycustomer(cid, licenses) VALUES (1, 5);
INSERT INTO mycustomer(cid, licenses) VALUES (2, 5);

    Request 1                            Request2
BEGIN TRANSACTION ISOLATION 
LEVEL SERIALIZABLE;
                                         BEGIN TRANSACTION ISOLATION 
                                         LEVEL SERIALIZABLE;
SELECT * from mydevice where cid = 1;

                                         SELECT * from mydevice where cid = 2;
INSERT INTO mydevice(id, cid, status) 
VALUES (1, 1, 'ok');

                                         INSERT INTO mydevice(id, cid, status)         
                                         VALUES (2, 2, 'ok');
commit;
(=ok)                                 
                                         commit;
                                         (=rollback)

据我了解,请求 1 和请求 2 中的插入与之前的读取不冲突,因此不应出现任何错误。为什么我收到“错误:由于事务之间的读/写依赖性而无法序列化访问”。

正如您可以想象的那样,我无法发生上述行为,因为无论其详细信息如何,每个并发请求都会回滚。在我的业务场景中,我希望并发请求仅在为同一单个客户插入数据(根据示例设备)时才回滚。

这些操作是从 Java 应用程序执行的,原则上我正在考虑创建一个锁定表来满足我的需求。有任何想法吗?

非常感谢!


来自事务隔离 http://www.postgresql.org/docs/current/static/transaction-iso.html page:

在查询执行期间获取的特定锁将取决于查询使用的计划,并且在执行过程中多个细粒度锁(例如元组锁)可以组合成更少的粗粒度锁(例如页锁)。事务以防止用于跟踪锁的内存耗尽。

...

  • 顺序扫描始终需要关系级谓词锁。这可能会导致序列化失败率增加。

An EXPLAIN在那SELECT可以告诉您正在采取什么查询计划,但如果表很小(或为空!),PostgreSQL 几乎肯定会选择顺序扫描而不是引用索引。这将导致整个表上的谓词锁,每当另一个事务对表执行任何操作时都会导致序列化失败。

在我的系统上:

isolation=# EXPLAIN SELECT * from mydevice where cid = 1;
                        QUERY PLAN                        
----------------------------------------------------------
 Seq Scan on mydevice  (cost=0.00..23.38 rows=5 width=46)
   Filter: (cid = 1)
(2 rows)

您可以尝试添加索引并强制它使用该索引:

isolation=# CREATE INDEX mydevice_cid_key ON mydevice (cid);
CREATE INDEX
isolation=# SET enable_seqscan = off;
SET
isolation=# EXPLAIN SELECT * from mydevice where cid = 1;
                                    QUERY PLAN                                    
----------------------------------------------------------------------------------
 Index Scan using mydevice_cid_key on mydevice  (cost=0.00..8.27 rows=1 width=46)
   Index Cond: (cid = 1)
(2 rows)

然而,这不是正确的解决方案。让我们回溯一下。

可序列化的目的是保证事务将具有与相继运行的事务完全相同的效果,尽管您实际上是同时运行这些事务。 PostgreSQL 没有无限的资源,因此虽然它确实对查询实际访问的数据设置了谓词锁,但“数据”可能不仅仅意味着“返回的行”。

PostgreSQL 在认为可能存在问题时而不是在确定存在问题时选择标记序列化失败。 (因此它将行锁推广为页锁。)这种设计选择会导致误报,例如您的示例中的情况。误报不太理想,但是,它不会影响隔离语义的正确性。

错误信息是:

ERROR:  could not serialize access due to read/write dependencies among transactions
DETAIL:  Reason code: Canceled on identification as a pivot, during commit attempt.
HINT:  The transaction might succeed if retried.

这个提示是关键。您的应用程序需要捕获序列化失败并重试整个操作。任何时候都是如此SERIALIZABLE正在发挥作用——尽管存在并发性,它仍能保证串行正确性,但如果没有应用程序的帮助,它就无法做到这一点。换句话说,如果您实际上正在进行并发修改,那么 PostgreSQL 满足隔离要求的唯一方法就是要求您的应用程序对其自身进行序列化。因此:

重要的是,使用此技术的环境具有处理序列化失败的通用方法(始终返回 SQLSTATE 值“40001”),因为很难准确预测哪些事务可能有助于读/写依赖关系并且需要回滚以防止序列化异常。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PostgreSQL 9.2.1 中具有可序列化隔离的谓词锁定 的相关文章

  • 如何使用SpringBoot + JPA存储PostgreSQL jsonb?

    我正在开发一个迁移软件 该软件将消耗来自 REST 服务的未知数据 我已经考虑过使用 MongoDB 但我决定不使用它而使用 PostgreSQL 读完后this https blog codeship com unleash the po
  • TypeORM 插入带有外键的行

    我之间有 OneToMany 关系聊天室1 M gt 留言我遇到的问题是 每当我尝试插入一条消息 或大量消息 时 ChatRoom 的外键为空 此外 我正在上传我的设置 Entity messages export class Messag
  • 如何使用diesel-rs选择色谱柱的子集?

    我现在花了几个小时的时间来查询表的可用列的子集以及在其中包含计算 我知道这不是在选择查询中执行计算的最佳方式 但现在 我只是在开发一个原型 它应该是可行的 我在用diesel rs作为后端实现中所有数据库操作的 ORM 数据将存储在 Pos
  • Postgres 服务器性能在达到一定数量的记录后急剧下降

    我正在使用游标从大型 postgres 表中检索记录 4亿条记录 使用子表对数据进行分区 我的游标定义为 select from parent table order by indexed column 同时使用 JDBC 和 psql 前
  • TransactionScope 在某些机器上自动升级到 MSDTC?

    在我们的项目中 我们使用 TransactionScope 来确保我们的数据访问层在事务中执行其操作 我们的目标是not要求在我们的最终用户的计算机上启用 MSDTC 服务 问题是 在我们一半的开发人员机器上 我们可以在禁用 MSDTC 的
  • PSQLException 没有被捕获

    我正在使用 Tomcat 6 和 Postgresql 8 4 我的代码如下所示 try Prepared statement inserting something catch final PSQLException e LOG log
  • Laravel 5.3 Schema::create ENUM 字段是 VARCHAR

    我刚刚创建了新的迁移 运行后我看到了我的领域type 不是 ENUM 类型 它有一个改为 VARCHAR 255 类型 Schema create payments function Blueprint table table gt inc
  • Ansible 创建可以访问所有表的 postgresql 用户?

    这应该很简单 我想要创建一个 Ansible 语句来创建一个 Postgres 用户 该用户具有特定数据库的连接权限以及对该特定数据库中所有表的选择 插入 更新 删除权限 我尝试了以下方法 name Create postgres user
  • 与 PostgreSQL CTE 的一般并行性

    我正在处理一些大数据 并且在查询中获取并行计划是必要的 我也很喜欢使用 CTE 来表达我的查询 但根据 PostgreSQL 的文档 我不太确定 CTE 是否对并行性造成严重限制 Here https www postgresql org
  • 查询外键列可以为NULL的地方

    我想获取数据 如果orgid 2或者如果根本没有行uid orgid is an integer 我能想到的最接近的事情就是做IS NULL但我没有得到数据uid没有一个orgid排 任何想法 select u uid u fname u
  • 在 postgreSQL 上选择大写表名不起作用[重复]

    这个问题在这里已经有答案了 我在 windows7 和 python3 4 4 上使用 psycopg2 我想从大写名称的表中获取数据 但我无法弄清楚 谁能帮我 总是这样返回relation table does not exist我想让
  • PostgreSQL C 函数建议

    有人可以给我一个关于自定义函数的初步尝试的提示吗 我需要用 2 个参数构造查询 一个 varchar 和一个 unix 时间戳 一个整数 我花了 3 个小时才得到下面的几行结果 查询测试可以是 select from pdc posot c
  • Python 的分布式锁管理器

    我有一堆具有多个实例的服务器 这些实例访问的资源对每秒的请求有硬性限制 我需要一种机制来锁定所有正在运行的服务器和实例对此资源的访问 我在github上找到了一个restful分布式锁管理器 https github com thefab
  • PostgreSQL 函数/存储过程 CURRENT_TIMESTAMP 不变

    我想跟踪函数内的执行时间 作为示例 我有以下状态跟踪表 CREATE TABLE status table run id numeric NOT NULL start ts timestamp 6 without time zone NOT
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • Postgres jsonb数组:查询非空交集

    假设我有一个名为的 JSONB 列value在表中t 这些 JSON 的内部是tags字段是字符串列表 我想对这些标记的 JSON blob 进行查询 foo or bar 所以假设表数据如下所示 value tags other tags
  • 如何使用PostGIS将多边形数据转换为线段

    我在 PostgreSQL PostGIS 中有一个多边形数据表 现在我需要将此多边形数据转换为其相应的线段 谁能告诉我如何使用 PostGIS 查询进行转换 提前致谢 一般来说 将多边形转换为线可能并不简单 因为没有一对一的映射 http
  • 查找 PostgreSQL 中所有范围集合的所有交集

    我正在寻找一种有效的方法来查找时间戳范围集之间的所有交集 它需要与 PostgreSQL 9 2 配合使用 假设这些范围代表一个人可以见面的时间 每个人都可以有一个或多个空闲时间范围 我想找到all可以召开会议的时间段 即所有人都有空的时间
  • 如何在不运行 PostgreSQL 服务器的情况下初始化 PostgreSQL 数据库

    在初始化脚本中 我想初始化 PostgreSQL 目录 但在此阶段不需要 也不希望 正在运行的 PostgreSQL 服务器 如果我只是创建集群 作为用户postgres initdb D 但是 我还需要创建 PostgreSQL 角色 创
  • 在 PostgreSQL 中使用月份名称排序

    我有一个表 其中有一个字段 Month Name 它包含月份的名称 我想按月份名称排序 不是按字母顺序 而是按实际顺序 例如一月 二月等 如何使用 PostgreSQL 实现此操作 有什么方法可以将月份名称转换为其数值吗 id billed

随机推荐

  • PHP - 一小时后检查 json 值

    我创建了一个函数 它使用 json 获取 Twitter 计数 但是 我想在一段时间后 例如一个小时 再次检查一次 但目前它每次加载页面时都会进行检查 以及这会影响页面加载时间 已经有一个 PHP 函数可以完全满足我的要求 但我不记得它了
  • HTTP GET 请求、ASP - 我迷路了!

    将 VBScript 与 ASP 结合使用 我尝试设置一个 HTTP GET 请求 该请求将访问一个页面 该页面又生成一行 ASCII 非 HTML 然后 我想将 ASCII 行 包含由分号分隔的 4 个值 推断回原始 ASP 页面中的 4
  • 如何在 POST 请求后返回重定向到 Django 中的上一页

    我正在编写一个新闻网站 在详细新闻页面中 有一个评论喷泉 如果人们想发表评论 他们需要先登录 我想让他们登录成功后 页面可以返回到上一个新闻页面 这是我的观点 py def newsDetailView request news pk ne
  • Rails 3 库只有在需要时才加载

    我正在尝试在 Rails 3 中加载 Tokbox SDK 我已将该库放置在 lib 目录中 因此目前我的目录结构如下所示 libopentok rb OpenTok异常 rbOpenTokSDK rb会话 rb 我使用 applicati
  • 如何将所有 C# 8 可空引用警告视为错误?

    使用 Visual Studio 2019 v16 3 2 将 NET Core 3 0 项目设置为 C 8 并启用可为 null 的引用类型
  • 如何在 Xcode 中创建具有多列的 UI TableView?

    我正在使用 Xcode 开发 iOS 8 应用程序 我需要在一个视图中显示一张包含多列和多行数据的表 Example Name Time In Time Out ETA Johnnys Supplies 8 30AM 9 00AM 10 1
  • 从pdf文档中提取图像

    我知道以前也有人问过类似的问题 但是它们已经过时了 有些可以追溯到 2006 年 我有一个 net 3 5 应用程序 带有 iTextSharp 5 我正在转换为 net core iText 7 它从 FedEx 跟踪文档中提取签名 并通
  • 从另一个类文件访问 C# 表单文本框

    我想从另一个类文件 例如chartscopier cs 访问Form1元素 但我无法从chartscopier cs更改textbox1文本 我怎样才能做到这一点 这是我的代码 Form1 cs namespace TEST public
  • 插入带有标识列的 Oracle 表时如何使用 %ROWTYPE?

    我有一个 Oracle 12c 数据库 其中有一个包含标识列的表 CREATE TABLE foo id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY bar NUMBER 现在我想使用 P
  • Android:应用程序小部件配置活动的行为与活动不同(编辑自:Android:AppWidget 未嵌入主屏幕)

    在这里编辑 下面是原始帖子 我已将原来的问题缩小为 对于常规活动和应用程序小部件配置活动 主页键的行为根本不同 我用以下最小活动进行了测试 public class TestActivity extends Activity Logger
  • 如何在 Android 中为 ExoPlayer 设计自定义搜索栏和音量控制

    我努力了this https stackoverflow com questions 24772985 how can i design the custom seekbar in android and this http www and
  • 使用ImageMagick/ZBar读取二维码

    我有扫描的图像文件 我对其进行了一些预处理 并使它们看起来像这样 我手机的 ZBar 应用程序可以很好地读取此二维码 但是zbarimg似乎想不通 我在 ImageMagick 中尝试了各种方法以使其更流畅 smooth morpholog
  • 使用 OpenSSL 库在 C++ 中生成 SHA-3 哈希值

    我广泛搜索了使用 OpenSSL 最近实现的 SHA 3 算法进行散列的代码示例 但没有找到任何代码示例 有关于 SHA 1 和 SHA 3 的代码示例 但在库文件夹中快速搜索发现 OpenSSL v1 1 1 中甚至没有 SHA3 函数名
  • 另一台计算机上的目录 - 登录凭据

    我的应用程序需要访问远程计算机上的文件 需要用户名和密码才能访问它 我试图找出目录是否存在 使用 Directory Exists 来验证我可以建立 连接 使用远程目录时有没有办法提供用户名和密码 当前存在返回 false Cheers 不
  • 如何使用维基百科的 Web API 检索某人的传记信息?

    我正在努力通过维基百科的 Web API 从该人的维基百科页面检索该人的一些特定生物详细信息 我需要检索一个人的生物信息框 我找到了如何检索内容框 介绍段落等 下面的 URL 用于检索 wiki 网页的第一个介绍段落 https en wi
  • 在 super.init 之前的表达式中使用初始化属性时出现 Swift 错误

    这并不重要 并且有解决方法 但它令人困惑 请参阅下面的最小示例 我指的是一个已初始化的属性 但在调用 super init 之前 为什么下面所示的语句会出现编译错误 在表达式的右手中使用属性与在左手中使用属性有什么特别之处吗 我浏览了 Sw
  • 在 Webfaction 上设置 Redis

    设置需要哪些步骤Redis http redis io 数据库上网派 http www webfaction com affiliate xeli共享托管帐户 介绍 由于 Webfaction 服务器的特殊环境限制 安装说明并不那么简单 尽
  • New 与 Malloc,当重载 New 时

    我超载了new and delete实现我自己的小对象 线程安全分配器 问题是当我超载时new 我不能使用new不破坏普遍因果关系或至少不破坏编译器 我发现的大多数例子都在哪里new超载 使用Malloc 进行实际分配 但根据我对 C 的理
  • 从所有表中删除外键关系

    我有一个包含多个表的数据库 许多表的字段具有外键约束 我想截断表 然后用新数据重新填充它们 并且我还想删除外键 因为某些关系已经改变 基本上 我想再次从头开始构建 FK 约束 如何从所有表中删除当前的 FK 约束 您可以使用 informa
  • PostgreSQL 9.2.1 中具有可序列化隔离的谓词锁定

    我已经仔细阅读了关于事务隔离的 postgres 文档 http www postgresql org docs current static transaction iso html建议在我的其他问题 https stackoverflo