当前位置: 首页 > 知识库问答 >
问题:

访问独占锁源

邢飞昂
2023-03-14

我在第一个事务中运行以下查询:

BEGIN ISOLATION LEVEL repeatable read;
SELECT balance from "Users" WHERE id = 1 FOR UPDATE;
UPDATE "Users" SET "balance"="balance"+1 WHERE id = 1;
   

然后是第二个,来自不同的连接,这是完全相同的。在选择...对于更新,它正在等待。

然后我运行下面的代码来查看锁

select t.relname,l.locktype,l.tuple,page,virtualtransaction,pid,mode,granted from pg_locks l, pg_stat_all_tables t where l.relation=t.relid order by relation asc;

它显示行锁(ROW SHARE,ROW EXCLUSVE),这很好。但我也看到了

Users   tuple   9   0   11/17085    199957  AccessExclusiveLock TRUE

根据文档,AccessExclusiveLock来自:

通过ALTERTABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER和VACUUM FULL命令获取。这也是未显式指定模式的lock TABLE语句的默认锁定模式。

我没有显式地做其中的任何一个,我在文档中找不到这个锁是如何隐式地获得的。而且,元组锁类型和9是什么意思?

更新#1:

我使用以下查询获取更多信息:

SELECT a.datname,
         l.relation::regclass,
         l.transactionid,
         l.mode,
         l.GRANTED,
         a.usename,
         a.query,
         a.query_start,
         age(now(), a.query_start) AS "age",
         a.pid
FROM pg_stat_activity a
JOIN pg_locks l ON l.pid = a.pid
ORDER BY a.query_start;   

所以确实数据库是相同的,查询是被阻止的那个。

mydb    "Users"     AccessExclusiveLock TRUE    appuserdev  SELECT balance from "Users" WHERE id = 1 for update;    2021-08-30 08:06:38.864007+00   00:08:06.978082 205464

共有1个答案

壤驷阳波
2023-03-14

您正在阅读的文档适用于表上的 AccessExclusiveLock。但你看到的不是桌子锁。我不认为非表的锁定模式在任何地方都有明确记录,但您通常可以通过类比来弄清楚。

另一方面,我也看不到你所看到的。我看到元组上持有的是ExclusiveLock,而不是AccessExclusiveLock。

 类似资料:
  • 在分布式Java桌面应用程序通过JDBC访问的特别请求的DB2表中,我每天都会多次收到以下场景: > 客户机A想要插入新的寄存器,并在表上获得一个IX锁,X锁在每个新行中; 其他客户端想要执行SELECT,被授予表上的IS锁,但应用程序卡住了; 客户机A继续工作,但是插入和更新查询没有被提交,锁没有被释放,并且它继续收集X个锁到每一行; 客户端 A 退出,其工作未提交。其他客户端最终获取其 SEL

  • 问题内容: 我正在编写一个程序,该程序将协调实时数据库中的最终交易。我正在进行的工作无法作为set操作完成,因此我使用了两个嵌套游标。 我在对每个客户端进行协调时需要对事务表进行排它锁,但是我想释放该锁,并让其他人在我处理的每个客户端之间运行查询。 我想在行级别而不是表级别上执行排他锁,但是到目前为止,我读到的内容说如果其他事务在隔离级别上运行(这对我来说),我将无法执行。 我是否正确获取了表级互

  • 我有以下功能,由多个进程同时使用。但是我有时会在插入操作中遇到重复错误。我认为这是锁的问题,所以我改成了 ACCESS EXCLUSIVE 锁,但这不好,因为它锁定了整个桌子。使用共享行独占模式似乎可以正常工作,但我对性能和访问有一些疑问。其他进程将能够访问该表?与前一个锁相比,此锁更慢(行独占)?

  • 我在Linux上,我想在大约5-10个进程之间共享内存(每个进程是一个C程序)。我知道如何使用POSIX信号量(sem_open、sem_wait、sem_post等)或其他信号量(semctl、semget、semop等)来实现这一点。问题是我只知道如何做独占信号量锁。我想要非专属锁。 在我的应用程序中,只有一个进程写入共享内存,而所有其他进程只读取它。我希望能够对信号量进行非独占读锁(就像sh

  • 如何获得整个Postgres表的锁,这样就没有其他进程可以更新表中的任何行(但仍然可以使用SELECT读取行)?我认为我想要的锁类型是EXCLUSIVE,但我不确定如何使用ecto查询为整个表获取这样的锁。 谢谢

  • 主要内容:1 同步队列的结构,2 锁的获取与释放,3 acquire独占式获取锁,3.1 tryAcquire尝试获取独占锁,3.2 addWaiter加入到同步队列,3.3 acquireQueued结点自旋获取锁,3.4 selfInterrupt自我中断,4 release独占式锁释放,4.1 unparkSuccessor唤醒后继结点,5 acquirelnterruptibly独占式可中断获取锁,,,,,,,,,详细介绍了AQS中的同步队列以及同步状态的独占式获取、释放的原理。 1 同