我们的文章会在微信公众号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)

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