PostgreSQL Oracle 兼容性之 - select for update of column_name (change to table_name or table_alias)

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

标签

PostgreSQL , Oracle , select for update of column


背景

当一个SELECT中包含多张表时(比如JOIN),FOR UPDATE可以指定要LOCK哪张表的匹配到的ROWS。

例如

https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm#SQLRF01702

The following statement locks only those rows in the employees table with purchasing clerks located in Oxford. No rows are locked in the departments table:

SELECT e.employee_id, e.salary, e.commission_pct  
   FROM employees e JOIN departments d  
   USING (department_id)  
   WHERE job_id = 'SA_REP'  
   AND location_id = 2500  
   FOR UPDATE OF e.salary  
   ORDER BY e.employee_id;  

PostgreSQL 对应语法

create table employees(department_id int, job_id text, employee_id int, salary float, commission_pct float);  
create table departments(department_id int, location_id int);  
  
insert into employees values (1, 'SA_REP', 1, 100, 1);  
insert into employees values (1, 'SA_REP123', 1, 100, 1);  
insert into departments values (1, 2500);  

语法如下,只是将列名改成表名或ALIAS,另外,order by需要放到前面。

postgres=# explain SELECT e.employee_id, e.salary, e.commission_pct  
   FROM employees e JOIN departments d  
   USING (department_id)  
   WHERE job_id = 'SA_REP'  
   AND location_id = 2500  
   ORDER BY e.employee_id   
   FOR UPDATE OF e;  -- order by 放前面  
  
                                      QUERY PLAN                                        
--------------------------------------------------------------------------------------  
 LockRows  (cost=182.79..182.84 rows=4 width=32)  
   ->  Sort  (cost=182.79..182.80 rows=4 width=32)  
         Sort Key: e.employee_id  
         ->  Hash Join  (cost=58.86..182.75 rows=4 width=32)  
               Hash Cond: (d.department_id = e.department_id)  
               ->  Seq Scan on departments d  (cost=0.00..123.62 rows=45 width=10)  
                     Filter: (location_id = 2500)  
               ->  Hash  (cost=58.62..58.62 rows=19 width=30)  
                     ->  Seq Scan on employees e  (cost=0.00..58.62 rows=19 width=30)  
                           Filter: (job_id = 'SA_REP'::text)  
(10 rows)  

我们还可以观察被LOCK的行

1、创建行锁观测插件

https://www.postgresql.org/docs/10/static/pgrowlocks.html

postgres=# create extension pgrowlocks ;  
CREATE EXTENSION  

2、在事务中执行以上LOCK的SQL,在其他会话中观测被锁的行

可以看到只有employees被LOCK

postgres=# select * from pgrowlocks('employees');  
 locked_row | locker  | multi |   xids    |     modes      |  pids     
------------+---------+-------+-----------+----------------+---------  
 (0,1)      | 1001814 | f     | {1001814} | {"For Update"} | {26460}  
(1 row)  

departments没有被锁

postgres=# select * from pgrowlocks('departments');  
 locked_row | locker | multi | xids | modes | pids   
------------+--------+-------+------+-------+------  
(0 rows)  

使用关联查询,可以看到被锁的行的记录

postgres=# SELECT * FROM employees AS a, pgrowlocks('employees') AS p  
  WHERE p.locked_row = a.ctid;  
 department_id | job_id | employee_id | salary | commission_pct | locked_row | locker  | multi |   xids    |     modes      |  pids     
---------------+--------+-------------+--------+----------------+------------+---------+-------+-----------+----------------+---------  
             1 | SA_REP |           1 |    100 |              1 | (0,1)      | 1001814 | f     | {1001814} | {"For Update"} | {26460}  
(1 row)  

3、如果不使用for update of ,则会锁住所有JOIN表的行。

postgres=# begin;  
BEGIN  
postgres=# SELECT e.employee_id, e.salary, e.commission_pct  
postgres-#    FROM employees e JOIN departments d  
postgres-#    USING (department_id)  
postgres-#    WHERE job_id = 'SA_REP'  
postgres-#    AND location_id = 2500  
postgres-#    ORDER BY e.employee_id   
postgres-#    FOR UPDATE  
postgres-# ;  
 employee_id | salary | commission_pct   
-------------+--------+----------------  
           1 |    100 |              1  
(1 row)  

观测

postgres=# select * from pgrowlocks('employees');  
 locked_row | locker  | multi |   xids    |     modes      |  pids     
------------+---------+-------+-----------+----------------+---------  
 (0,1)      | 1001826 | f     | {1001826} | {"For Update"} | {26460}  
(1 row)  
  
postgres=# select * from pgrowlocks('departments');  
 locked_row | locker  | multi |   xids    |     modes      |  pids     
------------+---------+-------+-----------+----------------+---------  
 (0,1)      | 1001826 | f     | {1001826} | {"For Update"} | {26460}  
(1 row)  
  

PostgreSQL for update更细致的用法

在对主外键表的主表加LOCK时,可以指定是否需要LOCK referenced的COLUMN。

FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE and FOR KEY SHARE are locking clauses;   
  
they affect how SELECT locks rows as they are obtained from the table.  
  
The locking clause has the general form  
  
FOR lock_strength [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ]  
where lock_strength can be one of  
  
UPDATE  -- 当前事务可以改所有字段  
NO KEY UPDATE  -- 当前事务可以改除referenced KEY以外的字段  
SHARE    -- 其他事务不能改所有字段  
KEY SHARE  -- 其他事务不能改referenced KEY字段  

参考

https://www.postgresql.org/docs/10/static/pgrowlocks.html

《并发事务, 共享行锁管理 - pg_multixact manager for shared-row-lock implementation》

《PostgreSQL add 2 DML LOCK TUPLE MODE to 4》

《PostgreSQL How to deal TUPLE LOCK : 2 - "one|more transactions waiting one|more transactions release tuple lock"》

《PostgreSQL How to deal TUPLE LOCK : 1 - "One transaction lock single or multiple tuples | rows"》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
7月前
|
关系型数据库 分布式数据库 数据库
PolarDB PostgreSQL版:Oracle兼容的高性能数据库
PolarDB PostgreSQL版是一款高性能的数据库,具有与Oracle兼容的特性。它采用了分布式架构,可以轻松处理大量的数据,同时还支持多种数据类型和函数,具有高可用性和可扩展性。它还提供了丰富的管理工具和性能优化功能,为企业提供了可靠的数据存储和处理解决方案。PolarDB PostgreSQL版在数据库领域具有很高的竞争力,可以满足各种企业的需求。
|
3月前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
626 2
|
7月前
|
人工智能 Oracle 关系型数据库
一篇文章弄懂Oracle和PostgreSQL的Database Link
一篇文章弄懂Oracle和PostgreSQL的Database Link
|
7月前
|
SQL Oracle 关系型数据库
常用数据库的分页语句(mySQL、oracle、PostgreSQL、SQL Server)
常用数据库的分页语句(mySQL、oracle、PostgreSQL、SQL Server)
|
Oracle 关系型数据库 数据库
PostgreSQL和Oracle两种数据库有啥区别?如何选择?
PostgreSQL和Oracle两种数据库有啥区别?如何选择?
532 0
|
SQL Oracle 关系型数据库
物化视图(Oracle与PostgreSQL对比)
物化视图(Oracle与PostgreSQL对比)
|
SQL Oracle 关系型数据库
Oracle,Postgresql等数据库使用
Oracle,Postgresql等数据库简单使用
174 0
Oracle,Postgresql等数据库使用
|
SQL Oracle 关系型数据库
Polar DB-O (兼容 Oracle 语法版本)和Polar DB PostgreSQL 版本概述(二)
Polar DB-O (兼容 Oracle 语法版本)和Polar DB PostgreSQL 版本概述(二)
1848 0
|
7月前
|
存储 Oracle 关系型数据库
PolarDB 开源版通过orafce支持Oracle兼容性
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB开源版通过orafce支持Oracle兼容性 .测试环境为m...
143 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
373 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多