C#:如何在MySql回滚中捕获异常

时间:2015-03-17 08:13:35

标签: c# mysql entity-framework

我正在使用Entity Framework连接到MySql数据库。一些长查询超时,然后我的应用程序崩溃。在事件查看器中,我看到了这个例外:

Application: MyApp.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
Stack:
at MySql.Data.MySqlClient.NativeDriver.ExecutePacket(MySql.Data.MySqlClient.MySqlPacket)
at MySql.Data.MySqlClient.NativeDriver.SendQuery(MySql.Data.MySqlClient.MySqlPacket)
at MySql.Data.MySqlClient.Driver.SendQuery(MySql.Data.MySqlClient.MySqlPacket)
at MySql.Data.MySqlClient.Statement.ExecuteNext()
at MySql.Data.MySqlClient.PreparableStatement.ExecuteNext()
at MySql.Data.MySqlClient.PreparableStatement.Execute()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(System.Data.CommandBehavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at MySql.Data.MySqlClient.MySqlTransaction.Rollback()
at MySql.Data.MySqlClient.MySqlTransactionScope.Rollback(System.Transactions.SinglePhaseEnlistment)
at MySql.Data.MySqlClient.MySqlPromotableTransaction.System.Transactions.IPromotableSinglePhaseNotification.Rollback(System.Transactions.SinglePhaseEnlistment)
at System.Transactions.DurableEnlistmentAborting.EnterState(System.Transactions.InternalEnlistment)
at System.Transactions.DurableEnlistmentActive.InternalAborted(System.Transactions.InternalEnlistment)
at System.Transactions.TransactionStateAborted.EnterState(System.Transactions.InternalTransaction)
at System.Transactions.TransactionStateActive.Rollback(System.Transactions.InternalTransaction, System.Exception)
at System.Transactions.EnlistableStates.Timeout(System.Transactions.InternalTransaction)
at System.Transactions.Bucket.TimeoutTransactions()
at System.Transactions.BucketSet.TimeoutTransactions()
at System.Transactions.TransactionTable.ThreadTimer(System.Object)
at System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.TimerQueueTimer.CallCallback()
at System.Threading.TimerQueueTimer.Fire()
at System.Threading.TimerQueue.FireNextTimers()
at System.Threading.TimerQueue.AppDomainTimerCallback()

因此,当命令超时时,它似乎正在尝试回滚。在这次回滚期间,似乎失败了。

围绕NonQuery的try-catch没有捕获此异常。我的代码:

                try
                {
                    using (MyDB db = new MyDB())
                    {
                        db.Database.CommandTimeout = 240;
                        using (var tran = new TransactionScope())
                        {
                            db.MyTable.AddRange(dataToSave);
                            db.SaveChanges();
                            tran.Complete();
                        }
                    }
                }
                catch (Exception ex)
                {
                    monitor.OnException(ex);
                }

那么如何捕获回滚异常呢?当发生这种情况时,我不希望我的应用程序完全崩溃。

1 个答案:

答案 0 :(得分:0)

没有回答直接问题 - 但它看起来并没有正确使用TransactionScope。看起来TransactionScope的目的是比常规数据库事务高一级。例如。见.net docs中的例子 您最好使用普通的常规数据库事务来避免类似的问题。