遇到一个由于事务控制不当造成错误的Bug
2004-07-09 22:59
501 查看
我们的发货单在审核时,要在发货单明细所对应的业务记录中登记发货单号,这样用户在查看业务记录中可以直接看到该业务记录是在哪一个发货单中发出的。
前几天客户报告了一个Bug,业务数据在审核发货后,发货单号没有设置;但是单据已经成功地审核了;这个Bug是偶尔才会出现的,出现条件不明,找了很久都没有找到原因。
前几天想了一个笨办法,把一个出这样问题的数据库的LOG文件Tranlate成了SQL脚本,然后在脚本中查找出问题的业务单据和对应的发货单做过哪些修改,最后终于找到了问题的原因所在,原来就是对事务的控制不正确造成的。
在系统的早期版本中,发货单的审核是专门通过一个函数来实现的,在这个函数中完成将发货单据设置为已审核、修改库存等操作,并在函数中进行了判断,成功则Commit否则Rollback,而在“审核”按钮的Click事件中则仅仅判断是否审核成功,不成功则退出;
这样做本来没有什么问题,但是在原有的开发人员离开后,接手的程序员没有很好地理解原有系统的设计架构,对于“审核后要设置业务单据的发货单号”这个功能写在“审核”按钮的Click事件中了,这样审核操作就被分成了两个事务了,而且一个很糟糕的问题是在新增加的这段程序中没有进行Commit!于是“审核后要设置业务单据的发货单号”这个操作是否会被提交就只能看用户在审核后会做些什么操作了,一般情况下都会提交的(我猜是在窗口直接关闭时提交的),但是如果用户在审核后添加一条新单据,然后取消,那么这个操作就会被Rollback了(取消中有Rollback),这样就会造成前面所说的Bug。
吸取的教训:
1.首先是事务的提交不应该放在函数中,函数中应该仅仅进行逻辑的判断,并返回是否成功,而对函数功能的返回结果进行检测,并对事务进行管理是事件的任务,这样即使在事件中有多个函数调用,也能够保证一个事件中只有一个事务;
2.今天看《CSDN开发高手》上的一篇文章,里面讲到在事件中不应该存放任何业务逻辑,业务逻辑都应该以单独的方法或函数进行封装,而在事件中应该只是调用并检测返回值,而不应该在事件中直接写业务逻辑,对照这次的问题,深以为然;
3.在事件中对数据库的操作完成后一定要对事务进行处理;
4.一定要有文档、明确的注释或者自注释性好的程序,详细的并且和程序完全同步的文档很难做到,那么就尽量的把程序的注释写好,这样可以保证后续的开发人员可以理解以前的设计思路;
回头要把1、2、3三条加到开发规范中。
前几天客户报告了一个Bug,业务数据在审核发货后,发货单号没有设置;但是单据已经成功地审核了;这个Bug是偶尔才会出现的,出现条件不明,找了很久都没有找到原因。
前几天想了一个笨办法,把一个出这样问题的数据库的LOG文件Tranlate成了SQL脚本,然后在脚本中查找出问题的业务单据和对应的发货单做过哪些修改,最后终于找到了问题的原因所在,原来就是对事务的控制不正确造成的。
在系统的早期版本中,发货单的审核是专门通过一个函数来实现的,在这个函数中完成将发货单据设置为已审核、修改库存等操作,并在函数中进行了判断,成功则Commit否则Rollback,而在“审核”按钮的Click事件中则仅仅判断是否审核成功,不成功则退出;
这样做本来没有什么问题,但是在原有的开发人员离开后,接手的程序员没有很好地理解原有系统的设计架构,对于“审核后要设置业务单据的发货单号”这个功能写在“审核”按钮的Click事件中了,这样审核操作就被分成了两个事务了,而且一个很糟糕的问题是在新增加的这段程序中没有进行Commit!于是“审核后要设置业务单据的发货单号”这个操作是否会被提交就只能看用户在审核后会做些什么操作了,一般情况下都会提交的(我猜是在窗口直接关闭时提交的),但是如果用户在审核后添加一条新单据,然后取消,那么这个操作就会被Rollback了(取消中有Rollback),这样就会造成前面所说的Bug。
吸取的教训:
1.首先是事务的提交不应该放在函数中,函数中应该仅仅进行逻辑的判断,并返回是否成功,而对函数功能的返回结果进行检测,并对事务进行管理是事件的任务,这样即使在事件中有多个函数调用,也能够保证一个事件中只有一个事务;
2.今天看《CSDN开发高手》上的一篇文章,里面讲到在事件中不应该存放任何业务逻辑,业务逻辑都应该以单独的方法或函数进行封装,而在事件中应该只是调用并检测返回值,而不应该在事件中直接写业务逻辑,对照这次的问题,深以为然;
3.在事件中对数据库的操作完成后一定要对事务进行处理;
4.一定要有文档、明确的注释或者自注释性好的程序,详细的并且和程序完全同步的文档很难做到,那么就尽量的把程序的注释写好,这样可以保证后续的开发人员可以理解以前的设计思路;
回头要把1、2、3三条加到开发规范中。
相关文章推荐
- 登录远程桌面时遇到“由于客户端检测到一个协议错误(代码0x1104)”
- 一个由于spring事务引起的bug
- NSCFString !!!通常遇到这个东西造成崩溃都是由于NSString类型实用不当。应仔细检查
- IIS中遇到无法预览的问题(HTTP 错误 401.3 - Unauthorized 由于 Web 服务器上此资源的访问控制列表(ACL)配置或加密设置,您无权查看此目录或页面。)
- 今天遇到一个由于内存访问越界而引起的bug
- Linux环境下段错误的产生原因及调试方法小结 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多、花费时间最长的问题就是
- 登录远程桌面时遇到“由于客户端检测到一个协议错误(代码0x1104)”
- IIS中遇到无法预览的问题(HTTP 错误 401.3 - Unauthorized 由于 Web 服务器上此资源的访问控制列表(ACL)配置或加密设置,您无权查看此目录或页面。)
- 当一个数据库插入事务由于错误被回滚时,被插入表中标识字段的值该发生怎么样的变化?
- JCO3调用SAP多个API时,需注意事务控制在一个session内
- 今天遇到的一个无聊编译错误:C1900:IL P1 P2版本不匹配 (罪魁祸首是AMD X2 4000+?。。)
- VS2012遇到一个问题:"链接器工具错误 LNK2026 XXX模块对于 SAFESEH 映像是不安全的"
- springmvc+mybatis+maven项目集成的时候遇到一个问题,项目搭起来以后,http请求怎么都进不到controller中,页面直接返回404错误,控制台没有报任何错误,请大神帮我看看
- 遇到一个<iostream>引发的非常难缠的连接错误LNK2001
- 写反转二叉树中遇到的一个小Bug
- Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
- myeclipse debug的时候遇到的一个错误
- 今天改bug遇到一个ie8样式错乱问题
- 解决SQL Server 2008 错误15023:当前数据库中已存在用户或角色,SQLServer2008,错误15023 在使用SQL Server 2008时,我们经常会遇到一个
- SecureCRT 遇到一个致命的错误且必须关闭