1、 VB 中的事务处理有一下两种方式:1. conn.BeginTrans 开始执行语句conn.Execute sqlIf Err.Number = 0 Thenconn.CommitTrans -提交事務Elseconn.RollbackTransactionMsgBox “失败“End If2.On Error GoTo err_transintTrans = newConn.BeginTrans 开始事务newConn.Execute sqlnewConn.CommitTrans 提交事务intTrans = 0newConn.Close 关闭连接MsgBox “OK“exit_tran
2、s:Set newConn = Nothing 释放对象Exit Sub 退出过程err_trans: 错误跳到这儿处理如果是事务处理中出错,则事务回滚If intTrans = 1 ThennewConn.RollbackTransEnd IfResume exit_trans看起来两种方式都没什么问题,但是在我的项目里使用第一种方式却遇到了一个很奇怪的错误,大家见 下图:很明显我使用的是 sql,不是存储过程,而且我的 sql 在查询分析器里运行的完全正常,它却说我有误,真是让我百思不得其解。更加奇怪的是,这个错误只在项目生成 exe 以后才会冒出来,也就是说在开发阶段,在 VB 工程里面
3、运行的是好好的,一旦到开发 的差不多了,打包生成 exe 文件,生成的过程不会出错,运行到特定代码调用这里的时候才会出错!这实在是个郁闷的问题,因为 在项目刚开始的时候一般不会生成 exe 文件来测试运行,而是直接在 VB 开发环境下运行,在这种情况下是运行的好好的, 所以到了项目后期可着实让我忙乱了好久,一直找不到原因,不知道大家有没有遇到过后来我使用了 2 方法,这个就没出问题了,不过还是有些地方要注意的,我在这里提醒一下大家吧,也算是对自己研究的总结:首先看如下代码:On Error GoTo err_transintTrans = newConn.BeginTrans 开始事务sql
4、= “insert into Sales(dish_id,uid) values (8,2);insert into Sales(dish_id,uid) values (8,2);“ 这里面有两句 sql,在查询分析器里执行都是没有问题的newConn.Execute sqlnewConn.CommitTrans 提交事务intTrans = 0newConn.Close 关闭连接MsgBox “OK“exit_trans:Set newConn = Nothing 释放对象Exit Sub 退出过程err_trans: 错误跳到这儿处理如果是事务处理中出错,则事务回滚If intTrans
5、 = 1 ThennewConn.RollbackTransMsgBox “false“End IfResume exit_trans执行的过程中没遇到任何问题,弹出“OK“,下面我们改一下 sql,将第一句的 id 值插入字符串aaaasql = “insert into Sales(dish_id,uid) values (aaaa,2);insert into Sales(dish_id,uid) values (8,2);“意料之中,弹出了“false“,事务回滚了,而且数据库中的数据也没有增加,下面再做另外一个实验:将第二句的 id 值插入字符串aaaasql = “insert i
6、nto Sales(dish_id,uid) values (8,2);insert into Sales(dish_id,uid) values (aaaa,2);“再次执行,让我惊讶的是居然弹出了“OK“,怎么会这样呢,急忙查看数据库发现数据并没有增加,还好!静下心来思考,一番,大概对 VB 的事务形式做了如下推断:1.正常情况下,正常执行,这个没有任何问题2.如果传给 Execute 方法的 sql 不是一条语句,而是多条语句的,那么:a.如果第一条语句发生了错误,那么它会跳到 newConn.RollbackTrans代码处,正常的回滚事务,如果在这 里我们需要返回值或者给出提示的话是
7、可以给出正确的提示的(可以返 回 false 或者提示 操作失败)b.如果在这多条 sql 中,不是第一条发生错误的,那么就有问题了,你会发现,这时候无法给出正确的提示了,操作人员会看到返回 true,或者提示操作成功,可是鬼魅的是数据库里并没有增加记录(包括前面正常的数据也没有被插入),我通过单步调试发现,确实程序的并没有执行到newConn.RollbackTrans 这句代码,可是数据确实回滚了,这说明了第一条语句执行成功,VB 接收到了这个返回值,就把整个事务给 commit 了,也就是说这个回滚根本不是 VB 里面的 newConn.RollbackTrans 代码来完成的,而是数据
8、库完成的(字符型换成整型失败)由于一些特殊的业务需要,我们经常会出现拼接 sql 的情况,也就是下面的情况:For j = 0 To 10 注意减 1sql=sql & “insert into Sales(dish_id,uid) values.“Next j我这里只是一些事例代码,但是可以看出上面的 sql 已经是 10 条 sql 了,如果这时候调用 newConn.Execute sql,那么按照前面的分析,如果错误不是发生在第一条 sql 而是在后面的 sql 的话,那么你的得到的返回值或者提示是不正确的,也就是你看到了操作成功,但是实际上并没有数据的情况(事实证明确实如此)。解决的
9、办法很简单,在 for 之前开始事务,并在其中一句一句执行 sql,在 next 后面做事务的处理,如下代码:On Error GoTo err_transintTrans = conn.BeginTrans 开始事务X = countFor i = 0 To Xsql=“insert into Sales(dish_id,uid) values.“conn.Execute sqlNext jconn.CommitTrans 提交事务intTrans = 0MsgBox “OK“exit_trans:Exit Function 退出过程err_trans: 错误跳到这儿处理如果是事务处理中出错,则事务回滚If intTrans = 1 Thenconn.RollbackTransMsgBox “false“End IfGoTo exit_trans 跳转到 exit_trans