PostgreSQL的锁定

摇滚音乐是什么

锁定是指在某个事务正在访问记录时,防止其他事务访问该记录的机制。

为了确保在PostgreSQL中的事务中同时执行,可以对表和行显式获取锁。此外,大多数PostgreSQL命令在执行SQL时,会在后台自动获取适当模式的锁,以确保被引用的表在命令执行期间没有被其他方式删除或更改。

表锁定

在中文中,可以这样表达:使用LOCK语句来进行表级锁。

LOCK [TABLE] table_name [IN lock_mode MODE] [NOWAIT]

我会打开两个终端来尝试一下。

transaction_a=# BEGIN;
transaction_a=# LOCK TABLE hoge_table IN EXCLUSIVE MODE;

transaction_b=# BEGIN;
transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga';
-- トランザクションaでロック中のテーブルにUPDATEをかけているため、waitになる

transaction_a=# COMMIT;
transaction_b=# UPDATE num -- UPDATE分が実行される

※ 立即返回错误:如果没有获取到锁,则不等待直接返回错误

摘要

由于有多种锁定模式,请参考官方文档。

行锁

在行级别进行锁定可以使用SELECT FOR UPDATE或SELECT FOR SHARE作为SELECT语句的选项。

我要打开两个终端来试试看。

transaction_a=# BEGIN;
transaction_b=# BEGIN;

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;
transaction_b=# SELECT * FROM hoge_table WHERE id = 1;
-- ロックしようとしている行の変更がトランザクションaでコミットされてないため、ここでwaitになる

transaction_a=# COMMIT;

transaction_b=# -- SELECT文の結果が表示される

死锁

死锁是指两个事务互相等待对方释放锁而无法继续进行的状态。

让我们来考虑下面这个例子。

transaction_a=# BEGIN;
transaction_b=# BEGIN;

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;

transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 2;
transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;
-- トランザクションaでコミットされていないためwaitになる。トランザクションbはトランザクションaが完了するのを待つ

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 2;
-- トランザクションbでコミットされていないためwaitになる。トランザクションaはトランザクションbが完了するのを待つ
-- トランザクションaもトランザクションbも、お互いのトランザクションが完了するのを待っているため、これ以上進まない。そのため、デッドロックが発生する
ERROR:  deadlock detected
DETAIL:  Process 93169 waits for ShareLock on transaction 112598; blocked by process 93173.
Process 93173 waits for ShareLock on transaction 112596; blocked by process 93169.

transaction_a=# SELECT * FROM hoge_table;
-- トランザクションがアボートされているのでエラーになる
ERROR:  current transaction is aborted, commands ignored until end of transaction block

在这种情况下,无论是交易a还是交易b都在等待彼此的交易完成,无法继续进行处理。这就是死锁,为了解决这个问题,可以通过强制终止其中一个交易来完成另一个交易的处理。

建议的锁

在使用SQL语句进行自动锁定或显式锁定之外,如果希望进行应用程序特定的独占控制,可以使用建议性锁定。建议性锁定能够有效地应用于难以与MVCC方式兼容的锁定策略。例如,如果需要跨事务进行独占控制,则可以使用会话级别的锁定。

请参阅

    • 13.3. 明示的ロック

 

    内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 4.5
广告
将在 10 秒后关闭
bannerAds