专栏首页AustinDatabasesPostgresql select 语句 share VS update 用过吗?

Postgresql select 语句 share VS update 用过吗?

for

Postgresql select 语句不够用吗, select for share ,select for udpate 这样的语句我从来没有用过,是不是多余。

回答是:NO

曾经还听到一个声音,select = select for share 没差的,到底是不是这样

首先要确认一点的是,无论是 share 还是update 都是因为在业务中的逻辑造成你要访问的数据需要保护,所以如果你还没有用过,可能你的业务比较简单,或者你的业务并不简单,只是你没有考虑某些问题,而从未使用过他们。

假设我们下面的图中的一个业务,下面是一个拍卖二手车的场景,在各地的拍卖都在买同一个二手车,人们在竞价,而这时有时间限制的,所以每个人读到的最近一次的购买人出的价格,并在这个价格上,提价。而这里面就会牵扯一个问题,如果我要在价格上更改,那这时的价格被我独占,否则我无法在得到一个价格后,更改的时候保证这个价格不变,然后在这个价格上我在加钱。

上面的业务场景,就设计到下面的这段截图的操作

1 首先他必须是一个事务

2 在我查询的时候我必须不能让人在更改价格

3 我要迅速的更新这个价格

4 然后释放,让别人继续出价

想想如果没有for update 这个语句,那在程序上要花费多大的力气来满足这个“事务”。

for update 将这一行数据上了锁,一个别人都不能对这行数据更改的锁,事情就到此为止了,NO NO NO

如果这时候多个人都要加 for update 锁会怎么样,那一定只能有一个人,加上这个锁。

session 1

session 2

从上图我们可以很清晰的看出,session2 无法将select for update 语句执行,一直在等待,他等待session 1 释放那个锁。session 2 只能等到 session 1 commit 后才能获得那个锁,进行更改,而那时数据一个改变,他读取的数据必然是session 1 已经更改的数据,周而复始。

我们可以把上面的过程叫做,安全更新。

那这for update 产生了什么锁我们的看一下

可以很清晰的看到 for update 加了 exclusivelock 排他锁

那问题来了,如果很多人都在竞争这行数据,那应用程序那边怎么办,都在等待,如果这边设计有问题,并没有超时设计,那其他的应用不就都卡死了。

那我们就的拿出for update NOWAIT 这条语句

session 1

session 2

从上图可以很清楚的看到,使用了for update nowait 则马上因为已经对那行数据上锁了,所以其他session 在去锁,就会报错,并提示,无法获得lock。

巧妙的使用这两句话,可以减少很多在应用程序中需要考虑的事情,简简单单就将事情解决了。

那么问题还没有完,如果两个事物锁定的记录部分重合,部分不重合,那我应该怎么办,业务逻辑中,例如抢注商标,在你确认的一刻,你有两个选择,你选择的这一批商标里面,有一部分已经被抢注了,一部分有,你此时是要不都注册,要不就都不注册,实际上此时你希望还有第三种选择,就是那个商标没有注册,你就马上注册上,其他就随它去。

那这时事情怎么办?shiyong skip locked 就可以满足上面的需求。

所以一个 for update 的用法和对应的业务逻辑都不同,适当的选择不同的方法可以事半功倍。

那说了这么半天,for share 到底又有几个意思。

相对于 for update for share 用法比较单纯,一句话,有我你别改,但都可以读。

最后一定会有一个问题,for share 和 for update 之间的最大的区别在哪里,下边这张图给出的答案。

附:上面使用的查询锁的view 代码

CREATE VIEW lockview AS

SELECT pid, virtualtransaction AS vxid, locktype AS lock_type,

mode AS lock_mode, granted,

CASE

WHEN virtualxid IS NOT NULL AND transactionid IS NOT NULL

THEN virtualxid || ' ' || transactionid

WHEN virtualxid::text IS NOT NULL

THEN virtualxid

ELSE transactionid::text END AS xid_lock, relname,

page, tuple, classid, objid, objsubid

FROM pg_locks LEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)

WHERE -- do not show our view’s locks

pid != pg_backend_pid();

本文分享自微信公众号 - AustinDatabases(AustinDatabases),作者:carol11

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 为什么 POSTGRESQL 给部分人一种,叫好不叫座的感觉

    最近看到有人说这样一个话题,postgresql 流行不起来,别学,还是某数据库有发展前途,换数据库不如自己加入到开发数据库的行列,改变那个数据库,不就行了。

    AustinDatabases
  • MYSQL SELECT 是多彩的, 业务如何应用适应不同场景

    看过不少文字, 实际上基本上很少看到select 语句被研究的, select 不就是select 出数据这么简单, NO NO NO .

    AustinDatabases
  • 12年的轮回,数据库的五代十国

    偶然翻到一篇 12年前的文字,题目是 《mysql即将成为下一个 oracle?》,看到前边我觉得有点意思,12年前的。2007年,MYSQL 就如此厉害,有了...

    AustinDatabases
  • 51单片机矩阵键盘C程序

    由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输出 由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输出

    Vance大飞
  • 右旋方阵

    lop
  • Python循环控制之for

    各位小伙伴们 大家周三愉快 今天我们要来共同探讨 另外一个在Python中 (严格的说实在所有语言中) 最重要的语句之一 For()循环控制语句 技术要点: f...

    企鹅号小编
  • 输入行列的值,打印出左手旋转矩阵。

    问题描述 输入行列的值,打印出左手旋转矩阵。 输入格式 输入一行,不超过20的m,n表示矩阵的行和列 。 样例输入 4 3 样例输出 1    2  ...

    lop
  • 经典!工业界深度推荐系统与CTR预估必读的论文汇总

    导读:本文是“深度推荐系统”专栏的第十一篇文章,这个系列将介绍在深度学习的强力驱动下,给推荐系统工业界所带来的最前沿的变化。本文主要根据Google推出的引领推...

    AI科技大本营
  • 刚开始玩openMP,总结一下遇到的一点小问题。

            首先,VS中设置步骤:         工程属性 —> C/C++ —> language 中的Open MP Suport中选择Yes 就OK...

    MachineLP
  • lodash源码分析之compact中的遍历

    本文为读 lodash 源码的第三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

    对角另一面

扫码关注云+社区

领取腾讯云代金券