PostgreSQL 使用advisory lock实现行级读写堵塞

简介:
+关注继续查看

标签

PostgreSQL , select for update , 读写冲突 , 读写堵塞 , advisory lock


背景

PostgreSQL的读写是不冲突的,这听起来是件好事对吧,读和写相互不干扰,可以数据库提高读写并发能力。

但是有些时候,用户也许想让读写冲突(需求:数据正在被更新或者删除时,不允许被读取)。

那么有方法能实现读写冲突吗?

PostgreSQL提供了一种锁advisory lock,可以实现读写堵塞的功能。

使用advisory lock实现行级读写堵塞

1. 创建表,注意使用一个唯一ID(用于advisory lock)

postgres=# create table ad_test(id int8 primary key, info text, crt_time timestamp);
CREATE TABLE

2. 插入测试数据

postgres=# insert into ad_test values (1,'test',now());
INSERT 0 1

3. 会话1,更新某一条记录

postgres=# begin;
BEGIN
postgres=# update ad_test set info='abc' where id=1;
UPDATE 1

4. 会话2,读这条记录

postgres=# select * from ad_test ;
 id | info |          crt_time          
----+------+----------------------------
  1 | test | 2017-05-07 15:57:42.201804
(1 row)

使用以上常规的方法,读写是不冲突的。

5. 会话1,更新这条记录的同时,使用advisory lock锁住这个ID

postgres=# begin;
BEGIN
postgres=# update ad_test set info='abc' where id=1 returning pg_try_advisory_xact_lock(id);
 pg_try_advisory_xact_lock 
---------------------------
 t
(1 row)

UPDATE 1

6. 会话2,查询这条记录时,使用advisory lock探测这条记录,如果无法加锁,返回0条记录。从而实现读写堵塞(实际上是隔离)。

postgres=# select * from ad_test where id=1 and pg_try_advisory_xact_lock(1);
 id | info | crt_time 
----+------+----------
(0 rows)

使用advisory lock,实现了读写冲突的需求(实际上是让读的会话读不到被锁的记录)。

adlock使用注意

advisory lock锁住的ID,是库级冲突的,所以使用时也需要注意哟。

advisory lock相关函数API的详细介绍

https://www.postgresql.org/docs/9.6/static/explicit-locking.html#ADVISORY-LOCKS

https://www.postgresql.org/docs/9.6/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS

advisory lock的其他应用

1. 《PostgreSQL upsert功能(insert on conflict do)的用法》

2. 《PostgreSQL 无缝自增ID的实现 - by advisory lock》

3. 《PostgreSQL 使用advisory lock或skip locked消除行锁冲突, 提高几十倍并发更新效率》

4. 《聊一聊双十一背后的技术 - 不一样的秒杀技术, 裸秒》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
Mysql Lock Wait
Mysql Lock Wait
110 0
|
5月前
|
SQL 存储 缓存
|
SQL 关系型数据库 数据库
Postgresql lock锁等待检查
查看锁等待sql with t_wait as ( select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.
1784 0
|
关系型数据库 MySQL 数据库
|
关系型数据库 MySQL 索引
RDS for MySQL 表上 Metadata lock 的产生和处理
RDS for MySQL 表上 Metadata lock 的产生和处理 1. Metadata lock wait 出现的场景 2. Metadata lock wait 的含义 3. 导致 Metadata lock wait 等待的活动事务 4. 解决方案
2952 0
|
关系型数据库 测试技术 C语言
PostgreSQL 另类advisory lock保证唯一约束法
在没有唯一约束或者主键约束时,数据库是不保证唯一性的。那么有什么手段来保证呢? 方法 1. 串行操作,先查询,如果没有查到记录,则插入。 这种方法效率非常低: 测试如下: postgres=# create table tbl(c1 text); CREATE TABLE
4325 0
相关产品
云数据库 Redis 版
云数据库 MongoDB 版
云数据库 RDS
推荐文章
更多