查看: 8505|回复: 58

[ 讨论]自制事务的“陷阱”

[复制链接]
认证徽章
论坛徽章:
26
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24夏利
日期:2013-08-13 23:25:29优秀写手
日期:2013-12-18 09:29:092014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11蓝色妖姬
日期:2015-03-19 09:37:00ITPUB年度最佳技术原创精华奖
日期:2015-03-19 09:43:24
发表于 2014-10-16 21:01 | 显示全部楼层 |阅读模式
自定义事务用: PRAGMA AUTONOMOUS_TRANSACTION 来控制;


很多朋友,为了在“复杂” 的程序里做一些“自由”的处理;“不由自主”的用上了 自制事务,或嵌套事务;

我倾向于使用 savepoint 的方法,做一个局部回滚点;
大部分时候,是能够解决问题的;


但是有的程序,已经很复杂了,为了快刀斩乱麻,只能用自制事务来处理;

下面我用几个例子讲一下陷阱;

例子1:

  1. declare xx varchar2(200);
  2. procedure reglog
  3. as
  4. PRAGMA AUTONOMOUS_TRANSACTION;
  5. begin

  6. update okform a set a.CAPTION='44445' where a.FORMCLASSNAME='TfrmPro1d';

  7.    --这里必须写 commit 或 rollack,否者也会报错
  8. end;

  9. begin
  10.   reglog;  
  11. end;

复制代码
执行失败,提示:

ORA-06519: 检测到活动的独立的事务处理, 已经回退
ORA-06512: 在 line 11
ORA-06512: 在 line 15



说明:凡是在自制事务里,只要做了有效的DML操作,就必须要有内部提交或回滚;

例子2:
先查询:  select CAPTION from OKFORM a where a.FORMCLASSNAME='TfrmProd'
得到 :   CAPTION的值为 : 变化前;


然后执行:

  1. declare xx varchar2(200);
  2. procedure reglog
  3. as
  4. PRAGMA AUTONOMOUS_TRANSACTION;
  5. begin
  6.   select   a.CAPTION   into xx  from OKFORM a where a.FORMCLASSNAME='TfrmProd';
  7.     dbms_output.put_line(xx); --得到:变化前

  8. end;

  9. begin
  10. update okform a set a.CAPTION='变化后' where a.FORMCLASSNAME='TfrmProd';

  11.   select   a.CAPTION   into xx  from OKFORM a where a.FORMCLASSNAME='TfrmProd';
  12.    dbms_output.put_line(xx); --得到:变化后
  13.   reglog;  

  14. end;
复制代码
说明:你会奇怪的发现,自制事务里select的数据 仿佛是一个独立会话中读取的数据;
它在整个事务里是一个独立的王国,不受未提交的数据影响;

例子3:

  1. declare xx varchar2(200);
  2. procedure reglog
  3. as
  4. PRAGMA AUTONOMOUS_TRANSACTION;
  5. begin


  6.    update okform a set a.CAPTION='44445' where a.FORMCLASSNAME='TfrmProd';

  7.     COMMIT;
  8. end;

  9. begin
  10. update okform a set a.CAPTION='333' where a.FORMCLASSNAME='TfrmProd';
  11.   reglog;  
  12.   
  13. end;

复制代码
执行失败,提示:
ORA-00060: 等待资源时检测到死锁
ORA-06512: 在 line 8
ORA-06512: 在 line 15

说明:第2个例子已经知道,自制事务类似于1个独立会话; 所以该例子中,两个相同记录的更新,全局的在前,自制的在后,那么必然因为两个会话同时一起操作同一个记录,而造成死锁;

所以,关键要了解自制事务本质上是个大的会话内部的一个小的独立会话, 这样你就会留意到可能发生的陷阱;

当然,从我的角度讲,简约设计,能不用自制事务,还是少用;
















论坛徽章:
533
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2014-10-16 22:07 | 显示全部楼层
牢牢记住TOM的话:
自治事务的唯一用途就是记录出错日志。其他用法可以说都是错的。

使用道具 举报

回复
招聘 : 系统分析师
论坛徽章:
483
马上有钱
日期:2014-02-19 11:55:14itpub13周年纪念徽章
日期:2014-09-29 01:14:14itpub13周年纪念徽章
日期:2014-10-08 15:15:25itpub13周年纪念徽章
日期:2014-10-08 15:15:25马上有对象
日期:2014-10-12 11:58:40马上有车
日期:2014-11-16 17:11:29慢羊羊
日期:2015-02-09 17:04:38沸羊羊
日期:2015-03-04 14:43:432015年新春福章
日期:2015-03-06 11:57:31ITPUB年度最佳版主
日期:2015-03-18 15:48:48
发表于 2014-10-17 10:00 | 显示全部楼层
除了记录日志,自治事务还可以增加重试次数等(性质和记录日志差不多)

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
发表于 2014-10-17 11:27 | 显示全部楼层
从不使用这些复杂的,偏门的特性
oracle很多特性不是随便可以放心使用的
比如物化视图,基本没实用价值
触发器绝对不用

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-09-23 06:00:14
发表于 2014-10-17 12:25 | 显示全部楼层
LZ总结的很好呀,

使用道具 举报

回复
认证徽章
论坛徽章:
26
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24夏利
日期:2013-08-13 23:25:29优秀写手
日期:2013-12-18 09:29:092014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11蓝色妖姬
日期:2015-03-19 09:37:00ITPUB年度最佳技术原创精华奖
日期:2015-03-19 09:43:24
发表于 2014-10-17 17:36 | 显示全部楼层
atgc 发表于 2014-10-17 11:27
从不使用这些复杂的,偏门的特性
oracle很多特性不是随便可以放心使用的
比如物化视图,基本没实用价值

触发器,我还是常用的;主要就是做 通过序列做自增长字段

使用道具 举报

回复
论坛徽章:
115
生肖徽章:狗
日期:2007-01-06 21:14:12马上有车
日期:2014-03-06 16:45:08马上加薪
日期:2014-05-09 12:27:582014年世界杯参赛球队: 英格兰
日期:2014-07-03 13:10:44青年奥林匹克运动会-竞技体操
日期:2014-09-10 15:30:57马上有钱
日期:2014-10-31 13:56:48美羊羊
日期:2015-03-04 14:48:582015年新春福章
日期:2015-03-06 11:57:31懒羊羊
日期:2015-04-23 19:26:10金牛座
日期:2015-09-17 08:21:44
发表于 2014-10-17 18:37 | 显示全部楼层
qingyun 发表于 2014-10-17 17:36
触发器,我还是常用的;主要就是做 通过序列做自增长字段

自增需要触发器吗?

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2014-10-17 19:35 来自手机 | 显示全部楼层
atgc 发表于 2014-10-17 11:27
从不使用这些复杂的,偏门的特性
oracle很多特性不是随便可以放心使用的
比如物化视图,基本没实用价值

关于绝对或尽可能的不用, 我非常同意!

使用道具 举报

回复
认证徽章
论坛徽章:
3
优秀写手
日期:2014-10-28 06:00:13暖羊羊
日期:2015-03-04 14:54:572015年新春福章
日期:2015-03-06 11:59:47
发表于 2014-10-17 21:17 | 显示全部楼层
暂时在开发中还没使用过自制事务。

使用道具 举报

回复
论坛徽章:
533
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2014-10-17 22:53 | 显示全部楼层
atgc 发表于 2014-10-17 11:27
从不使用这些复杂的,偏门的特性
oracle很多特性不是随便可以放心使用的
比如物化视图,基本没实用价值

物化试图实用价值大了,比如数据复制,存储预先计算结果(聚合汇总,连接等的结果)。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表