[ERROR]The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION

程序在调用Commit时,居然发生“The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION”的错误~ 到底是怎么一回事呢?


前阵子帮同事查问题时,程序的执行中,居然发生了以下的错误,

at System.Data.SqlClient.SqlConnection.OnError 
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
[ SqlException.Number : 3902, SqlException.LineNumber : 1, SqlException.State : 1 ]
  at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, TdsParserState state)
  at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, TdsParserState state)
  at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
  at System.Data.SqlClient.TdsParser.Run(RunBehavior run, SqlCommand cmdHandler, SqlDataReader dataStream)
  at System.Data.SqlClient.TdsParser.Run(RunBehavior run)
  at System.Data.SqlClient.SqlInternalConnection.ExecuteTransaction(String sqlBatch, String method)
  at System.Data.SqlClient.SqlConnection.ExecuteTransaction(String sqlBatch, String method)
  at System.Data.SqlClient.SqlTransaction.Commit()

还蛮奇怪的,于是问同事说,除了程序中的connection有起事务外,调用的Store Procedure有起事务吗?

查了一下,程序调用的SP中,都没有BEGIN TRAN呀~

同事怀疑是因为程序中调用Web Service所导致的,后来把那段程序mark起来还是一样的状况!

于是用SQL Server Profiler录看看到底是什么状况,结果发现程序执行到最后,TransactionID字段的值不见了,如下图,

image

当下觉得怪怪的,想说把那支SP拿来执行一下!

果然就发现了问题,就是因为程序执行的SP中会发生错误,这时因为“SET XACT_ABORT ON”,所以在事务里,如果有发生错误的话,就会自动Rollback。

但是那个错误,在.NET程序中并没有被Catch到,.NET程序以为这个SP执行是正确的,所以.NET程序要再调用Commit就会出现“The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION”的错误!

所以下次如果在程序中有起事务,而最后要Commit发生了一样的错误,请记得检查是不是执行SQL发生错误,而没有被程序Catch到哦!