Exceptions when rolling back a transaction - connection already closed?(回滚事务时出现异常 - 连接已关闭?)
问题描述
使用 Entity Framework 6.0.0,我在关闭事务时看到异常.
Using Entity Framework 6.0.0, I'm seeing an exception when closing a transaction.
我们一直在对表进行并发更改时遇到问题,所以我将它包装在一个事务中,现在我在回滚时遇到异常.
We'd been having problems with concurrent changes to the table, so I wrapped it in a transaction, and now I'm getting exceptions on rollback.
代码:
public LockInfo getSharedLock(string jobid)
{
using (var myDbContext = new MyDbContext())
{
using (var transaction = myDbContext.Database.BeginTransaction())
{
try
{
this.logger.log("Attempting to get shared lock for {0}", jobid);
var mylocks =
myDbContext.joblocks.Where(j => j.customerid == this.userContext.customerid)
.Where(j => j.jobid == jobid)
.Where(j => j.operatorid == this.userContext.operatorid);
var exclusiveLock = mylocks.FirstOrDefault(
j => j.lockstatus == LockInfo.LockState.Exclusive);
if (exclusiveLock != null)
{
this.logger.log("{0} already had exclusive lock, ignoring", jobid);
return LockInfo.populate(exclusiveLock);
}
var sharedLock = mylocks.FirstOrDefault(
j => j.lockstatus == LockInfo.LockState.Shared);
if (sharedLock != null)
{
this.logger.log("{0} already had shared lock, ignoring", jobid));
sharedLock.lockdt = DateTime.Now;
myDbContext.SaveChanges();
return LockInfo.populate(sharedLock);
}
var joblock = new joblock
{
customerid = this.userContext.customerid,
operatorid = this.userContext.operatorid,
jobid = jobid,
lockstatus = LockInfo.LockState.Shared,
sharedLock.lockdt = DateTime.Now
};
myDbContext.joblocks.Add(joblock);
myDbContext.SaveChanges();
transaction.Commit();
this.logger.log("Obtained shared lock for {0}", jobid);
return LockInfo.populate(joblock);
}
catch (Exception ex)
{
transaction.Rollback();
this.logger.logException(ex, "Exception in getSharedLock("{0}")", jobid);
throw;
}
}
}
}
您可以在上面的代码中看到日志记录.我们也在数据库中启用了日志记录.日志跟踪:
You can see the logging, in the code above. We have logging enabled in the database, too. The log trace:
===================
NORMAL TicketLockController.getLock("AK2015818002WL")
===================
SQL Opened connection at 9/22/2015 2:47:49 PM -05:00
===================
SQL Started transaction at 9/22/2015 2:47:49 PM -05:00
===================
NORMAL Attempting to get shared lock for AK2015818002WL
===================
SQL SELECT TOP (1) [Extent1].[customerid] AS [customerid]
,[Extent1].[jobid] AS [jobid]
,[Extent1].[lockdtdate] AS [lockdtdate]
,[Extent1].[lockdttime] AS [lockdttime]
,[Extent1].[operatorid] AS [operatorid]
,[Extent1].[lockstatus] AS [lockstatus]
,[Extent1].[changes] AS [changes]
FROM [dbo].[joblock] AS [Extent1]
WHERE ([Extent1].[customerid] = 'TESTTK')
AND ([Extent1].[jobid] = 'AK2015818002WL')
AND ([Extent1].[operatorid] = 'ADMIN')
AND (N'Exclusive' = [Extent1].[lockstatus])
===================
SQL SELECT TOP (1) [Extent1].[customerid] AS [customerid]
,[Extent1].[jobid] AS [jobid]
,[Extent1].[lockdtdate] AS [lockdtdate]
,[Extent1].[lockdttime] AS [lockdttime]
,[Extent1].[operatorid] AS [operatorid]
,[Extent1].[lockstatus] AS [lockstatus]
,[Extent1].[changes] AS [changes]
FROM [dbo].[joblock] AS [Extent1]
WHERE ([Extent1].[customerid] = 'TESTTK')
AND ([Extent1].[jobid] = 'AK2015818002WL')
AND ([Extent1].[operatorid] = 'ADMIN')
AND (N'Shared' = [Extent1].[lockstatus])
===================
SQL INSERT [dbo].[joblock] (
[customerid]
,[jobid]
,[lockdtdate]
,[lockdttime]
,[operatorid]
,[lockstatus]
,[changes]
)
VALUES (
@0
,@1
,@2
,@3
,@4
,@5
,NULL
)
===================
SQL Closed connection at 9/22/2015 2:47:50 PM -05:00
===================
EXCEPTION Unhandled exception caught: The underlying provider failed on Rollback.
===================
EXCEPTION Inner Exception: Value cannot be null.
Parameter name: connection
两次选择都成功,然后插入由于某种原因失败.抛出异常,并且由于某种原因连接在 Rollback() 执行之前关闭.
The two selects are succeeding, then the insert is failing for some reason. throwing an exception, and for some reason the connection is closing before the Rollback() executes.
任何想法我做错了什么?
Any ideas what I'm doing wrong?
==== 添加堆栈跟踪 ====
==== Adding stack traces ====
外部异常的堆栈跟踪:
at System.Data.Entity.Core.EntityClient.EntityTransaction.Rollback()
at korterra.kt_api.Shared.TicketLockWrangler.getSharedLock(String jobid)
at korterra.kt_ws.ApiControllers.Shared.TicketLockController.getSharedLock(TicketLockDTO ticketLockDTO)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
内部异常的堆栈跟踪:
at System.Data.Entity.Utilities.Check.NotNull[T](T value, String parameterName)
at System.Data.Entity.Infrastructure.Interception.DbTransactionInterceptionContext.WithConnection(DbConnection connection)
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Rollback(DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityTransaction.Rollback()
推荐答案
经过讨论,我开始记录异常,然后尝试回滚 - 这揭示了错误.
After the discussion, I started logging the exception before trying to roll back - and that revealed the error.
事务已死锁:
Exception in getSharedLock("ticketnumber123456"): An error occurred while updating the entries. See the inner exception for details.
Inner Exception: An error occurred while updating the entries. See the inner exception for details.
Inner Exception: Transaction (Process ID 139) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
从我所读到的,当你告诉一个事务已经成为死锁的牺牲品时,它已经被回滚了.也许这就是我们得到异常的原因?
From what I'm reading, when your told a transaction has been made a deadlock victim, it's already been rolled back. Perhaps that is why we're getting an exception?
修复似乎是识别我们何时死锁而不回滚,或者不使用事务,并在我们遇到主键违规时重试.
The fix seems to be either to recognize when we've deadlocked, and not rollback, or to not use transactions, and retry when we get a primary key violation.
这篇关于回滚事务时出现异常 - 连接已关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:回滚事务时出现异常 - 连接已关闭?
基础教程推荐
- 如何激活MC67中的红灯 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01