Oracle数据库,查询语句不会锁表,但PostgreSQL在开启事务后,查询数据表会锁表,在试图DROP/TRUNCATE TABLE时会一直等待。
--------------------------- Session A
drop table if exists t1;
-- 开启事务
begin;
-- 查询当前事务号
select txid_current();
-- 创建表&插入100w数据
create table t1(id int,c1 varchar(20));
-- 查询当前事务号
select txid_current();
insert into t1 select generate_series(1,1000000),'#TESTDATA#';
-- 提交事务
end;
--------------------------- Session B
-- 开启事务
begin;
-- 查询当前事务号
select txid_current();
-- 查询数据表
select count(*) from t1;
--------------------------- Session A
-- 重新回到Session A,删除数据表
drop table t1; -- 这时会一直等待
查询数据库锁信息:
testdb=# SELECT pid, relname , locktype, mode
testdb-# FROM pg_locks l JOIN pg_class t ON l.relation = t.oid
testdb-# AND t.relkind = 'r'
testdb-# WHERE t.relname = 't1';
pid | relname | locktype | mode
------+---------+----------+---------------------
1574 | t1 | relation | AccessShareLock
1585 | t1 | relation | AccessExclusiveLock
(2 rows)
发现查询t1(1574为Session B的pid)时会持有AccessShareLock,导致drop table一直等待该锁释放后才能执行。
参考:
https://www.postgresql.org/docs/11/static/explicit-locking.html