遇到一个由于事务控制不当造成错误的Bug [zt]

来源:互联网 发布:数控机床编程怎么复制 编辑:程序博客网 时间:2024/05/21 17:42
遇到一个由于事务控制不当造成错误的Bug

我们的发货单在审核时,要在发货单明细所对应的业务记录中登记发货单号,这样用户在查看业务记录中可以直接看到该业务记录是在哪一个发货单中发出的。

前几天客户报告了一个Bug,业务数据在审核发货后,发货单号没有设置;但是单据已经成功地审核了;这个Bug是偶尔才会出现的,出现条件不明,找了很久都没有找到原因。

前几天想了一个笨办法,把一个出这样问题的数据库的LOG文件Tranlate成了SQL脚本,然后在脚本中查找出问题的业务单据和对应的发货单做过哪些修改,最后终于找到了问题的原因所在,原来就是对事务的控制不正确造成的。

在系统的早期版本中,发货单的审核是专门通过一个函数来实现的,在这个函数中完成将发货单据设置为已审核、修改库存等操作,并在函数中进行了判断,成功则Commit否则Rollback,而在“审核”按钮的Click事件中则仅仅判断是否审核成功,不成功则退出;

这样做本来没有什么问题,但是在原有的开发人员离开后,接手的程序员没有很好地理解原有系统的设计架构,对于“审核后要设置业务单据的发货单号”这个功能写在“审核”按钮的Click事件中了,这样审核操作就被分成了两个事务了,而且一个很糟糕的问题是在新增加的这段程序中没有进行Commit!于是“审核后要设置业务单据的发货单号”这个操作是否会被提交就只能看用户在审核后会做些什么操作了,一般情况下都会提交的(我猜是在窗口直接关闭时提交的),但是如果用户在审核后添加一条新单据,然后取消,那么这个操作就会被Rollback了(取消中有Rollback),这样就会造成前面所说的Bug。

吸取的教训:
1.首先是事务的提交不应该放在函数中,函数中应该仅仅进行逻辑的判断,并返回是否成功,而对函数功能的返回结果进行检测,并对事务进行管理是事件的任务,这样即使在事件中有多个函数调用,也能够保证一个事件中只有一个事务;
2.今天看《CSDN开发高手》上的一篇文章,里面讲到在事件中不应该存放任何业务逻辑,业务逻辑都应该以单独的方法或函数进行封装,而在事件中应该只是调用并检测返回值,而不应该在事件中直接写业务逻辑,对照这次的问题,深以为然;
3.在事件中对数据库的操作完成后一定要对事务进行处理;
4.一定要有文档、明确的注释或者自注释性好的程序,详细的并且和程序完全同步的文档很难做到,那么就尽量的把程序的注释写好,这样可以保证后续的开发人员可以理解以前的设计思路;

回头要把1、2、3三条加到开发规范中。

原创粉丝点击