前两天调试程序发现提交的数据不完整,在执行DML语句后在一个事务里的增删、改操作中某些语句执行出异常,但是一个事务中之前执行的语句全部被提交,当时忙着调试就没去管,今天写了几个测试程序发现问题所在.
在使用System.Data.OracleClient.dll中OracleConnection访问Oracle10g数据库,在调用BeginTransaction方法开始事务时如果调用BeginTransaction(IsolationLevel) (该函数有两个重载版本),传递IsolationLevel.ReadCommitted时第一次调用时的事务是有效的,再次开始事务时,事务失效,在其间执行的DML语句都是单条作为一个事务来执行,如下所示:
using (IDbConnection conn = new OracleConnection(connectionString))
{
IDbTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "delete from tb_test";
//执行DML语句后在数据库里执行select * from v$transaction语句可以查到相应的事务
cmd.ExecuteNonQuery();
trans.Rollback();//此处回滚有效
}
using (IDbConnection conn = new OracleConnection(connectionString))
{
IDbTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "delete from tb_test";
//执行完后tb_test表中的数据将全部被删掉
cmd.ExecuteNonQuery();
//回滚无效,此处执行的每个DML单独作为一个事务被提交
//同样select * from v$transaction没有任何结果返回
trans.Rollback();
//trans.Dispose();
}
如果掉用无参数版本BeginTransaction()不会有上述现象,而在MSDN里写的IsolationLevel默认值就是ReadCommitted.
上述现象不知是因为System.Data.OracleClient.dll库是9i下实现,去访问10g,版本不兼容造成的还是本身的BUG,本人机器上没装
9i就没有去试过.不管怎么样这个问题比较让人困惑,也容易造成bug.