当前位置: 首页 > news >正文

读书笔记:数据库锁定机制:如何避免数据冲突

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。

本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。

数据库锁定机制:如何避免数据冲突

在开发多用户数据库应用时,最大的挑战之一就是如何在保证数据一致性的同时,让多个用户能够同时访问和修改数据。今天我们就来聊聊Oracle数据库中的锁定机制,以及如何避免常见的"丢失更新"问题。

什么是数据库锁?

想象一下图书馆里借书的情景:当一本书被借出时,其他读者就不能再借这本书了。数据库锁也是类似的机制,它用来管理对共享资源的访问。在数据库中,锁不仅用于锁定表中的行,还用于控制对存储过程等各种资源的并发访问。

为什么不同数据库的锁机制不同?

就像不同品牌的手机操作系统不同一样,Oracle、SQL Server、MySQL等数据库的锁实现方式也各不相同。我曾经使用过多种数据库,发现它们处理锁的方式差异很大:

  • 早期SQL Server使用页级锁(锁定整页数据),导致并发性能很差
  • Informix虽然支持行级锁,但开销很大,锁数量有限制
  • Oracle的行级锁则非常高效,无论锁定1行还是100万行,资源消耗几乎相同

常见问题:丢失更新

最典型的并发问题是"丢失更新"。举个员工信息更新的例子:

  1. 用户A查询员工信息(地址:旧地址)
  2. 用户B也查询同一员工信息
  3. 用户A修改地址为新地址并保存
  4. 用户B修改电话号码并保存

结果:用户B的更新会覆盖用户A的地址修改,导致地址又变回旧地址!

解决方案一:悲观锁

悲观锁就像"先占位再修改"的策略。具体做法是:

  1. 查询数据时立即锁定:SELECT ... FOR UPDATE NOWAIT
  2. 如果锁定成功,确保数据未被修改
  3. 执行更新并提交
-- 先锁定要修改的行
SELECT empno, ename, sal FROM emp 
WHERE empno = :empno 
FOR UPDATE NOWAIT;-- 确认锁定后执行更新
UPDATE emp SET ename = :ename, sal = :sal 
WHERE empno = :empno;
COMMIT;

优点:绝对安全,不会出现并发冲突
缺点:需要保持数据库连接,不适合Web应用

解决方案二:乐观锁

乐观锁就像"先修改再检查"的策略。常用实现方式有:

1. 版本号列法

给表添加一个版本号或时间戳列:

CREATE TABLE dept (deptno NUMBER(2),dname VARCHAR2(14),loc VARCHAR2(13),last_mod TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL
);

更新时检查版本号:

UPDATE dept 
SET dname = :dname, last_mod = SYSTIMESTAMP
WHERE deptno = :deptno 
AND last_mod = :original_last_mod;

如果返回0行更新,说明数据已被他人修改。

2. 校验和法

使用ORA_HASH等函数计算数据指纹:

-- 查询时计算哈希值
SELECT deptno, dname, loc, ORA_HASH(dname || '/' || loc) hash 
FROM dept WHERE deptno = 10;-- 更新时验证哈希
UPDATE dept SET dname = :dname
WHERE deptno = :deptno 
AND ORA_HASH(dname || '/' || loc) = :original_hash;

如何选择锁策略?

  • 客户端/服务器应用:优先考虑悲观锁,因为可以保持连接
  • Web应用:必须使用乐观锁,因为HTTP是无状态的
  • 推荐方法:时间戳版本列法,既高效又能记录修改时间
  • 遗留系统改造:校验和法侵入性最小

记住Oracle锁的关键特点:

  1. 事务是必要的,不要过早提交
  2. 行级锁没有额外开销
  3. 读不阻塞写,写不阻塞读
  4. 可以同时实现高并发和数据一致性

通过合理使用这些锁策略,你可以构建出既快速又可靠的数据库应用!

------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)

http://www.sczhlp.com/news/11225/

相关文章:

  • mysql8.0使用Percona-Server审计插件报错解决办法libstdc++.so.6: version `CXXABI_1.3.9 not found
  • 故障处理:troubleshooting row cache lock
  • Abogen - 强大的文本转语音工具,轻松将电子书转换为高质量有声书
  • DDS-TSN到底是如何实现的?
  • Perforce P4 DAM - 2D/3D视觉数字资产管理系统
  • 半模态对话框bindSheet的isShow属性
  • 2025年8月13日
  • 分布式数据高效可靠检索新方法
  • 完全免费还能私有化部署?现在的国产低代码平台太香了!
  • Selenium定位
  • Java方法(重载→递归)+数组
  • AI Compass前沿速览:RynnVLA视觉-语言-动作模型、GLM-4.5V 、DreamVVT虚拟换衣、 WeKnora框架、GitMCP、NeuralAgent桌面AI助手
  • 微分方程的应用(第12版)- A First Course in Differential Equations with Modeling Applications
  • react 同步更新状态
  • CF1408D Searchlights
  • 题解:SP707 TFSETS - Triple-Free Sets
  • Vue 命名规范指南
  • mq bug 处理
  • 从训练到推理:Intel Extension for PyTorch混合精度优化完整指南
  • Window系统怎么设置定时关机
  • node 运行项目报超内存
  • 如何恢复被删除的日志文件以追踪攻击者
  • 3.浮点数及其应用
  • Qt事件过滤器之eventFilter函数返回值
  • Ubuntu系统小优化
  • ARM CPU的 intrinsics指令集 - svsel_u32
  • PowerShell检查IP是否为保留IP
  • 第三十篇
  • 莫队卡常
  • CSP-S模拟10