PostgreSQL并发控制详解(2)

snail_aaa 2009-05-16 05:07:51
http://www.wohedb.com 中文数据库管理系统

9.3.2 行级锁
除了表级锁以外,还有行级锁。行级锁的模式有互斥和共享两种。当一个数据行被删除或更新时,事务会自动得到这个数据行上的互斥行级锁。一个事务获得的行级锁只有在事务提交或回滚以后才会被释放。行级锁不会影响查询操作,如果有其它事务企图更新同一个数据行,该事务将会进入等待状态,直到持有行级锁的事务被回滚或提交。如果一个命令只是想锁住数据行,而不是想更新数据行,可以使用SELECT FOR UPDATE,同一个事务以后发出的命令就可以随意地修改被锁住的数据行。



如果想得到一个数据行上的共享锁,使用命令SELECT FOR SHARE。多个不同的事务可以在同一个数据行上同时持有共享锁。如果一个事务已经在一个数据行上持有共享锁,那么其它的事务就不能更新和删除这个数据行,也不能在这个数据行上得到互斥锁。



PostgreSQL不会限制一个事务一次能同时锁住的数据行的最大数目,但每锁住一个数据行就会有一次写磁盘的操作。



除了表级锁和行级锁,数据库中还存在数据页级别的共享和互斥锁,数据页级别的锁用来协调对表的的某个数据页并发访问操作,它是由数据库自动得到和释放的。开发应用程序时不必关心数据页级别的锁,只要知道它存在就可以了。



9.3.3 死锁
使用锁来协调多个事务对表中的数据的并发访问,很容易产生死锁,即两个或多个事务中的每个事务都拥有其它的某个或多个事务需要的锁资源,所有的事务都会无限期地等待下去。



系统会自动检测数据库中是否有死锁发生,如果有,会回滚一个造成死锁的事务,让其它的因死锁而等待的事务继续执行。



9.3.4 建议锁(Advisory Locks)
PostgreSQL提供了一种被称为建议锁的锁机制。建议锁的含义是有应用程序自己特定的,何时得到和释放建议锁也是由应用程序自己控制的,数据库只是提供得到和释放建议锁的接口供用户使用。建议锁同事务没有任何关系,在一个事务中得到的建议锁,即使在事务被回滚以后仍然存在。建议锁的所有者是会话而非事务,一个会话可以多次得到同一个建议锁(如果一个会话执行了n次得到同一个建议锁的操作,那么它必须执行n次释放这个建议锁的操作,否则该建议锁不会被真正地释放,仍然被这个会话所有)。在一个会话结束后,该会话持有的所有建议锁都会被自动释放。



可以查看视图pg_locks得到当前会话持有的所有建议锁的列表。建议锁存放在数据库的共享内存中,数据库中的建议锁的最大数目受参数max_locks_per_transaction 和max_connections控制。



数据库提供的用于处理建议锁的函数参见第7.22节表7-50。

下面是一些使用建议锁的实例:



SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok



SELECT pg_advisory_lock(q.id) FROM

(

SELECT id FROM foo WHERE id > 12345 LIMIT 100;

) q;



9.4 在应用程序级别检查数据的一致性
因为PostgreSQL中的只读查询无论在任何隔离事务级别下都不会在读取的数据上加锁,一个事务读取的数据可能已被其它并发执行的事务修改。每个事务都会看到一个数据库内容的快照,并发执行的事务可能看到不同的数据库快照。如果事务想保证自己读取的数据在自己提交或回滚以前不被其它的事务修改,应该使用SELECT FOR UPDATE或SELECT FOR SHARE来读取数据(而不是只使用SELECT),也可以使用LOCK TABLE来锁住表,不让其它事务更新表中的数据。



如果应用程序希望一个事务在执行的过程中所引用的表的数据不能有任何变化,可以先用LOCK TABLE命令锁住所有的表,然后再执行其它的命令。



一般使用显示的加锁命令时,事务应该运行在Read Committed隔离级别下,也可以使用Serializable隔离级别。在Serializable隔离级别下使用LOCK TABLE命令时,注意LOCK TABLE命令应该作为事务发出的第一条命令。



9.5 锁与索引
PostgresSQL在访问索引时也会使用锁来控制对索引的并发访问,不同类型的索引的加锁模式如下:



B-tree 和GiST 索引

使用短期的共享或互斥数据页级别的锁来控制对索引的并发访问。在每个索引数据行被读取或删除以后,锁会被立即释放。不会出现死锁的情况。



哈希索引

使用共享或互斥数据页级别的锁来控制对索引的并发访问。在每个哈希桶被处理以后,锁会被立即释放。可能会出现死锁。



GIN 索引

使用短期的共享和互斥数据页级别的锁来控制对索引的并发访问。在每个索引数据行被读取或删除以后,锁会被立即释放 。GIN类型索引的插入操作可能素要比较大的工作量。



对标量数据类型建立索引时,应该使用B-tree索引。对非标量类型的数据建立索引,应该使用Gist或GIN索引。

...全文
453 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
百年树人 2009-05-29
  • 打赏
  • 举报
回复
iwlk 2009-05-29
  • 打赏
  • 举报
回复
有没有办法,让数据库不使用锁?
2021 云和恩墨大讲堂PPT汇总,共50份。 2021 云和恩墨大讲堂内容涵盖Oracle、MySQL、PG等多种数据库。 带你走进PG的世界 MySQL查询优化 Oracle数据库SQL执行计划的取得和解析 11gR2频繁遭遇Checkpoint incompelte 12C_19C统计信息最佳实践 并行不悖 - Oracle数据库的并行执行 抽丝剥茧_一起有关新冠病毒疫情的勒索病毒案例 从内存故障到CPU过高Oracle诊断案例(上) 从内存故障到CPU过高Oracle诊断案例(下) 从纸上谈兵到躬行实践-shared pool道法器术 高并发Oracle OLTP系统的故障案例分享 经典知识库:深入解析Oracle检查点 经典知识库:数据库对象命名设计规范手册 经典知识库:数据模型重构案例分享 经典知识库:性能优化那些事 经典知识库:ASM元数据简介及案例分享 经典知识库:MGR原理介绍与案例分享 经典知识库:MySQL常用运维工具小妙招集锦 经典知识库:MySQL故障诊断常用方法手册 经典知识库:Oracle 19c X86下移经验分享 经典知识库:Oracle DBA的SQL编写技能提升宝典 经典知识库:Oracle PDB Refresh实战分享 经典知识库:Oracle数据库索引分裂详解 经典知识库:PostgreSQL中的锁 经典知识库:SQL条件等价改写秘笈 如何实现海量数据迁移及落地实践 如何通过APEX 实现标准化运维 如何通过APEX实现标准化运维sql 深入解析:oracle drop table purge内部原理及异常恢复 数据时代万象更新-从数据库技术演进看国产数据库机遇 一次特殊的Oralce 硬解析性能问题的技术分享 CloudQuery 权限管理体系在证券行业的应用 DML操作时索引是如何同步变化的 MogDB优化入门 MySQL备份恢复工具应用场景和使用方法 MySQL的性能 MySQL中的索引探究 Oracle 12cR2 ADG LGWR Library Cache案例分享 Oracle 10046 Trace 的取得和解析方法 Oracle 基于AWR ASH的性能分析 Oracle DataGuard备份恢复最佳实践-姚远 Oracle Nologging全面总结 Oracle RAC 集群安装部署 Oracle RMAN 单实例异机迁移恢复(版本:11GR2) Oracle存储过程性能分析案例 Oracle技术加油站:快速处理紧急性能问题的工具与经验 Oracle诊断性能问题时常用脚本工具 PostgreSQL日常工作分享 PostgreSQL实践分享 wls、was中间件故障基本分析介绍
1.Go环境配置 1.1. Go安装 1.2. GOPATH 与工作空间 1.3. Go 命令 1.4. Go开发工具 1.5. 小结 2.Go语言基础 2.1. 你好,Go 2.2. Go基础 2.3. 流程和函数 2.4. struct 2.5. 面向对象 2.6. interface 2.7. 并发 2.8. 小结 3.Web基础 3.1 web工作方式 3.2 Go搭建一个简单的web服务 3.3 Go如何使得web工作 3.4 Go的http包详解 3.5 小结 4.表单 4.1 处理表单的输入 4.2 验证表单的输入 4.3 预防跨站脚本 4.4 防止多次递交表单 4.5 处理文件上传 4.6 小结 5.访问数据库 5.1 database/sql接口 5.2 使用MySQL数据库 5.3 使用SQLite数据库 5.4 使用PostgreSQL数据库 5.5 使用beedb库进行ORM开发 5.6 NOSQL数据库操作 5.7 小结 6.session和数据存储 6.1 session和cookie 6.2 Go如何使用session 6.3 session存储 6.4 预防session劫持 6.5 小结 7.文本文件处理 7.1 XML处理 7.2 JSON处理 7.3 正则处理 7.4 模板处理 7.5 文件操作 7.6 字符串处理 7.7 小结 8.Web服务 8.1 Socket编程 8.2 WebSocket 8.3 REST 8.4 RPC 8.5 小结 9.安全与加密 9.1 预防CSRF攻击 9.2 确保输入过滤 9.3 避免XSS攻击 9.4 避免SQL注入 9.5 存储密码 9.6 加密和解密数据 9.7 小结 10.国际化和本地化 10.1 设置默认地区 10.2 本地化资源 10.3 国际化站点 10.4 小结 11.错误处理,调试和测试 11.1 错误处理 11.2 使用GDB调试 11.3 Go怎么写测试用例 11.4 小结 12.部署与维护 12.1 应用日志 12.2 网站错误处理 12.3 应用部署 12.4 备份和恢复 12.5 小结 13.如何设计一个Web框架  13.1 项目规划  13.2 自定义路由器设计 13.3 controller设计 13.4 日志和配置设计 13.5 实现博客的增删改 13.6 小结  14.扩展Web框架 14.1 静态文件支持 14.2 Session支持 14.3 表单支持 14.4 用户认证 14.5 多语言支持 14.6 pprof支持 14.7 小结

56,687

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧