简体   繁体   English

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

[英]C#: How to catch exception in MySql rollback

I'm using Entity Framework to connect to a MySql database. 我正在使用实体框架连接到MySql数据库。 Some long queries are timing out and then my application crashes. 一些长时间的查询超时,然后我的应用程序崩溃。 In event viewer I see this exception: 在事件查看器中,我看到此异常:

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()

So it looks like it's trying to do a rollback when the command timeouts. 因此,看起来好像在命令超时时尝试回滚。 During this rollback something seems to fail. 在此回滚期间,某些操作似乎失败了。

The try-catch around the NonQuery is not catching this exception. 围绕NonQuery的try-catch不会捕获此异常。 My code: 我的代码:

                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);
                }

So how can I catch the rollback exception? 那么如何捕获回滚异常? I don't want my application to crash completely when this happens. 我不希望我的应用程序在这种情况下完全崩溃。

Not answering direct problem - but it doesn't look that you use TransactionScope correctly. 没有回答直接问题-但看起来您没有正确使用TransactionScope。 It looks that purpose of TransactionScope is one level above regular database transactions. 看起来TransactionScope的目的比常规数据库事务高一级。 Eg see example in .net docs 例如,请参阅.net文档中的示例
You probably better to use plain regular database transactions to avoid similar issues. 您最好使用普通的常规数据库事务来避免类似的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM