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

读书笔记:数据库事务处理的那些坑与妙招

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

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

数据库事务处理的那些坑与妙招

可重启进程:小心数据状态的"薛定谔猫"

想象一下你在批量更新100万条数据,突然更新到一半系统崩溃了。这时候数据库就像一只"薛定谔猫"——既不是完全更新成功,也不是完全失败,而是处于一种尴尬的中间态。

比如你想给所有记录的日期加1天:

UPDATE t SET last_ddl_time = last_ddl_time + 1;

如果中途失败,直接重跑会导致部分日期加1天,部分加2天,数据就乱套了。

解决方案:把数据"分块"处理,比如按首字母分批:

-- 先建个任务表记录处理进度
CREATE TABLE to_do AS 
SELECT DISTINCT SUBSTR(object_name,1,1) first_char FROM t;-- 分批处理
BEGINFOR x IN (SELECT * FROM to_do) LOOPUPDATE t SET last_ddl_time = last_ddl_time+1 WHERE object_name LIKE x.first_char||'%';DELETE FROM to_do WHERE first_char = x.first_char;COMMIT; -- 每批提交一次END LOOP;
END;

这样即使中断,也能从断点继续,不会重复处理。

自动提交:程序员钱包的隐形杀手

很多开发框架(如JDBC/ODBC)默认开启"自动提交"模式,这就像开车不系安全带——平时没事,一出事就要命。

看这个转账例子:

UPDATE accounts SET balance = balance-1000 WHERE account_id=123; -- 自动提交
UPDATE accounts SET balance = balance+1000 WHERE account_id=456; -- 自动提交

如果执行完第一条后系统崩溃,你的1000块就人间蒸发了!

保命建议:连接数据库后第一件事就是关掉自动提交:

Connection conn = DriverManager.getConnection(...);
conn.setAutoCommit(false); // 这句话值1000块!

分布式事务:数据库界的联合国

Oracle的分布式事务就像联合国会议——要么所有国家(数据库)都同意,要么全都不干。

假设你在北京更新本地数据,同时要更新纽约和伦敦的数据库:

UPDATE local_table SET x=5;              -- 北京
UPDATE remote_table@ny_db SET y=10;      -- 纽约
UPDATE remote_table@london_db SET z=15;  -- 伦敦
COMMIT; -- 要么三地都成功,要么全部回滚

这背后是"两阶段提交"协议:

  1. 协调者(北京)问各地:"准备好了吗?"
  2. 所有节点回复"YES"后,才正式提交

注意事项

  • 不能在国外直接COMMIT(必须回总部提交)
  • 不能在国外建表改结构(DDL操作)
  • 事务控制权由发起方掌握

自治事务:事务中的"独行侠"

自治事务就像公司里的特殊项目组——他们干活不影响主业务,自己独立提交。

典型应用场景:错误日志。即使主事务回滚,错误信息依然保留:

CREATE PROCEDURE log_error(err_msg VARCHAR2) ASPRAGMA AUTONOMOUS_TRANSACTION; -- 声明为自治事务
BEGININSERT INTO error_log VALUES(SYSDATE, err_msg);COMMIT; -- 自己单独提交
END;

使用时:

BEGIN-- 主要业务代码...some_operation();
EXCEPTIONWHEN OTHERS THENlog_error(SQLERRM); -- 记录错误(立即提交)RAISE; -- 主事务依然回滚
END;

这样即使业务操作失败回滚,错误日志依然保存完好。

总结:事务处理的黄金法则

  1. 简单至上:能用单条SQL就别用循环
  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.aitangshan.cn/news/48.html

相关文章:

  • arduino 工具栏消失
  • # 常见算法板子(一)
  • 【算法分享】字典树 — 插入、查询与状态标记详解
  • 8.10
  • Windows 2003 系统如何修改网卡DNS?
  • Python 内置模块 base64:编码与解码的艺术
  • Webstorm运行显示404 not found的问题解决方案。
  • 一文带你彻底学会 Git 代码管理
  • arcgispro的软件说明文档和使用技巧
  • InnoDB为什么不用跳表,Redis为什么不用B+树?
  • c++算法竞赛输入输出优化
  • JS中对输入的金额进行大写转换(支持两位小数)
  • 集训内容总结 day13:模拟赛 Round6
  • DUBBO通信框架
  • 利用几种阈值法从给定的图像中分割出目标,去除背景
  • centos系统,docker安装失败报错依赖问题。
  • nginx 日志路径配置修改
  • linux 文件命令
  • 8.5.5 编写信号处理程序
  • Dify入门系列(2)| 5 分钟部署 Dify:云服务 vs 本地 Docker
  • 图论杂题选做 20250802
  • EasyExcel 导入/出通用枚举映射
  • dp09
  • 克隆arcgispro-py3虚拟环境
  • Air780EGH硬件开发必备:UART串口电路设计最佳实践
  • bytes和基本数据类型之间的转换
  • 糟糕,生产环境频繁Full GC,怎么办?
  • CSP/NOIP常用模板大全₍^˶⦁༝⦁˶^₎◞ ̑̑
  • 洛谷P1525 [NOIP 2010 提高组] 关押罪犯(恭喜解锁拆点并查集!!)
  • Score Matching