这几天在调试程序时发现一个BUG。
流程是这样的:
1.前台ajax调用后台插入记录(记录分散在多个表中,用到了事务)
2.前台根据后台的返回值(如果返回值为成功,则再调用一下后台的查询方法,将数据显示到前台)
大致过程就是这样,非常简单的一个逻辑,错误就出现在第2步上,查询时总是报“数据库连接为空”起先以为操作数据库的底层出问题了,这样反复修改底层,尝试“创建新连接”、“打开连接”,总之怎么改都不行,比较诡异的是错误是断断续续的,有时好有时坏。
最后实在没办法了将代码还原到修改前的状态,重新调试发现执行代码时返回的顺序不正常(因为用到try{}catch{}finally{}),发现前台都已经获取到返回值了而finally里的代码确还没有执行,导致事务对像没有释放,执行查询时发现有事务对像,所以就用事务的连接了,这时才执行finally里的代码,事务对像才被释放了,然后再继续执行查询,但此时事务对像已经被销毁了,所以查询报错。
虽然找到错误原因了,但不知如何修改,反复看代码逻辑没发现哪里有问题,又经过N次调试修改,最终发现错误出现在“回调函数”中
// 最开始的写法大致是这样的 // 插入记录 function Save() { mainform.attr("action",actionRoot + "&method=AddLoadPlan"); LG.submitForm(mainform,function (data) { var win = parent || window; if (data.IsError) { win.LG.showError('错误:' + data.Message,function () { return data.IsError; }); } else { win.LG.showSuccess('保存成功',function () { return data.IsError; }); } }); } var isError = Save(); // 这里为查询记录 if (!isError) { dialog.close(); // 错误就出现在这里 Select(); }
// 修改后代码 function Save(callback) { mainform.attr("action",callback); } function savecallback(data) { var win = parent || window; if (data.IsError) { win.LG.showError('错误:' + data.Message,function () { return data.IsError; }); } else { win.LG.showSuccess('保存成功',function () { // 这里为查询记录 Select(); return data.IsError; }); } } var isError = Save(savecallback); if (!isError) { dialog.close(); }
总结: 归根结底还是ajax的同步异步没有用好,忽略了同步与异步的区别;为了界面的流畅我的ajax是异步执行,所以才会出现上面的问题;如果改为同步原来的代码也是可以正常执行的,但界面会在后台返回结果之前一直卡住不动.
异步:当ajax发送请求后,在等待server端返回的过程中,前台会继续执行ajax块后面的脚本,直到server端返回正确的结果才去执行success(回调函数)
同步:当ajax发送请求后,会停止执行ajax块后面的JS代码,直到ajax块执行完毕后时,才会继续执行后面的JS脚本。
原文链接:https://www.f2er.com/ajax/161295.html