我们的文章会在微信公众号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; -- 要么三地都成功,要么全部回滚
这背后是"两阶段提交"协议:
- 协调者(北京)问各地:"准备好了吗?"
- 所有节点回复"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;
这样即使业务操作失败回滚,错误日志依然保存完好。
总结:事务处理的黄金法则
- 简单至上:能用单条SQL就别用循环
- 明确控制:永远自己掌握事务开关
- 错误预案:提前想好失败后怎么恢复
- 慎用高级功能:自治事务是把双刃剑
记住:好的事务设计就像好的保险——平时感觉不到它的存在,关键时刻能救你一命。
------------------作者介绍-----------------------
姓名:黄廷忠 现就职:Oracle中国高级服务团队 曾就职:OceanBase、云和恩墨、东方龙马等 电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)