PostgreSQL中行锁的使用

 更新时间:2025年06月15日 14:50:30   作者:喝醉酒的小白  
PostgreSQL行锁分为共享锁和排他锁,用于控制并发事务对行数据的访问,共享锁允许多事务读取,排他锁独占访问,本文就来具体介绍一下行锁,感兴趣的可以了解一下

行锁(Row - level Locks)

在 PostgreSQL 中,行锁(Row - level Locks)是一种用于控制并发事务对特定行数据访问的机制。

行锁的类型

  • 共享锁(ShareLock) :如果事务 A 对某行加了共享锁,其他事务只能对该行加共享锁,而不能加排他锁。适用于读操作,允许多个事务同时读取同一行数据,但防止其他事务修改或删除该行。
  • 排他锁(ExclusiveLock) :如果事务 A 对某行加了排他锁,其他事务无论想要对该行进行读还是写操作都无法加锁。通常用于写操作,如 UPDATE、DELETE 等,确保在事务完成对该行的修改之前,其他事务无法对该行进行任何操作。

行锁的获取与释放

  • 获取 :当事务执行涉及到对某行数据的读写操作时,PostgreSQL 会自动为该行添加相应的锁。例如,执行 SELECT…FOR SHARE 或 SELECT…FOR UPDATE 语句时,会在查询结果中的行上添加共享锁或排他锁。
  • 释放 :行锁会在事务结束时自动释放,即当事务提交(COMMIT)或回滚(ROLLBACK)时,事务所持有的所有行锁都会被释放。

行锁的应用场景

  • 数据更新与删除操作 :在执行 UPDATE 或 DELETE 操作时,PostgreSQL 会对要更新或删除的行自动加排他锁,防止其他事务同时对这些行进行修改或删除操作,保证数据的一致性。
  • 防止幻读控制 :在可重复读隔离级别下,为避免幻读现象,事务在读取某行数据时会为其加共享锁,这样其他事务就不能对同一行数据进行插入、更新或删除操作。

查看行锁

可以通过查询 pg_locks 系统表来查看当前数据库中行锁的情况,例如:

SELECT * FROM pg_locks WHERE locktype = 'tuple';

需要注意的是,行锁虽然可以有效控制并发事务对行数据的访问,但在高并发场景下,过多的行锁可能会导致事务等待甚至死锁。因此,在设计数据库应用时,要合理控制事务的粒度和操作,尽量避免长时间持有行锁,以提高系统的并发性能。

PostgreSQL行锁机制详解

在这里插入图片描述

一、行锁实现原理

PostgreSQL的行锁通过元组(tuple)头部信息实现,采用多版本并发控制(MVCC)机制。与Oracle的ITL槽位和MySQL的bitmap方式不同,其特点包括:

  • 元组x m a x xmaxxmax字段记录事务ID和锁标记位
  • 共享锁(FOR SHARE)通过设置HEAP_XMAX_SHR_LOCK标记
  • 排他锁(FOR UPDATE)通过设置HEAP_XMAX_EXCL_LOCK标记
  • 锁信息不单独存储,直接附加在数据行上

二、使用方法

-- 排他锁(写锁)
BEGIN;
SELECT * FROM table WHERE id = 1 FOR UPDATE;
-- 执行更新操作
COMMIT;

-- 共享锁(读锁)
BEGIN;
SELECT * FROM table WHERE id = 1 FOR SHARE;
-- 允许其他事务加共享锁
COMMIT;

-- 非阻塞锁
SELECT * FROM table WHERE id = 1 FOR UPDATE NOWAIT;

-- 跳过已锁定行
SELECT * FROM table WHERE status = 'pending' FOR UPDATE SKIP LOCKED;

三、常见问题及解决方案

锁冲突

  • 现象:事务长时间等待
  • 排查方法:
SELECT pid, relation::regclass, locktype, mode 
FROM pg_locks 
WHERE relation = 'table_name'::regclass;

死锁检测

  • 自动检测:PostgreSQL默认开启死锁检测(deadlock_timeout=1s)
  • 手动排查:
SELECT * FROM pg_stat_activity 
WHERE wait_event_type = 'Lock';

锁升级问题

  • PostgreSQL行锁不会升级为表锁,与MySQL不同
  • 注意表级锁与行锁的共存规则

长时间锁持有

优化建议:

SET lock_timeout = '3s';
  • 缩短事务时间
  • 使用NOWAITSKIP LOCKED
  • 设置合理的锁超时时间

四、优化建议

优先使用READ COMMITTED隔离级别

利用隐藏的乐观锁版本字段实现无锁并发控制

监控工具组合:

-- 实时锁监控视图
SELECT * FROM pg_stat_activity 
JOIN pg_locks ON pg_stat_activity.pid = pg_locks.pid;

到此这篇关于PostgreSQL中行锁的使用的文章就介绍到这了,更多相关PostgreSQL 行锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:

相关文章

  • Postgresql中xlog生成和清理逻辑操作

    Postgresql中xlog生成和清理逻辑操作

    这篇文章主要介绍了Postgresql中xlog生成和清理逻辑操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 关于postgresql timestamp时间戳问题

    关于postgresql timestamp时间戳问题

    这篇文章主要介绍了关于postgresql timestamp时间戳问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Postgresql查询效率计算初探

    Postgresql查询效率计算初探

    这篇文章主要给大家介绍了关于Postgresql查询效率计算的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Postgresql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • postgresql 中的COALESCE()函数使用小技巧

    postgresql 中的COALESCE()函数使用小技巧

    这篇文章主要介绍了postgresql 中的COALESCE()函数使用小技巧,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL查看版本信息的操作

    PostgreSQL查看版本信息的操作

    这篇文章主要介绍了PostgreSQL查看版本信息的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL批量修改函数拥有者的操作

    PostgreSQL批量修改函数拥有者的操作

    这篇文章主要介绍了PostgreSQL批量修改函数拥有者的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 对PostgreSQL中的慢查询进行分析和优化的操作指南

    对PostgreSQL中的慢查询进行分析和优化的操作指南

    在数据库的世界里,慢查询就像是路上的绊脚石,让数据处理的道路变得崎岖不平,想象一下,你正在高速公路上飞驰,突然遇到一堆减速带,那感觉肯定糟透了,本文介绍了怎样对 PostgreSQL 中的慢查询进行分析和优化,需要的朋友可以参考下
    2024-07-07
  • PostgreSQL新手入门教程

    PostgreSQL新手入门教程

    本文介绍PostgreSQL的安装和基本用法,供初次使用者上手。以下内容基于Debian操作系统,其他操作系统实在没有精力兼顾,但是大部分内容应该普遍适用
    2014-06-06
  • PostgreSQL 使用raise函数打印字符串

    PostgreSQL 使用raise函数打印字符串

    这篇文章主要介绍了PostgreSQL 使用raise函数打印字符串,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL 删除表的具体使用小结

    PostgreSQL 删除表的具体使用小结

    PostgreSQL 使用DROP TABLE语句来永久删除数据库中的表格及其相关对象,这是一个不可逆的操作,会同时删除表中的所有数据,下面就来详细的介绍一下,感兴趣的可以了解一下
    2025-11-11

最新评论