如何解决即使有意中止,“交易已中止”也会被捕获
关于我如何使用 TransactionScope
的一些上下文,如果三个数据库的查询中的任何一个捕获到错误,目前在程序中,我做了它以便 TransactionScope
将 { {1}} 导致没有数据通过的所有内容。这部分程序运行良好。
另一个背景是我使用的框架是 ASP.NET Boilerplate。
由于保密原因,下面将包含代码减去一些细节。
dispose
现在的问题是,我使用的框架会将 public CUDResult TriTransaction(TransactItem[] item)
{
CUDResult result = new CUDResult();
using (TransactionScope ts = new TransactionScope())
{
try
{
result = InsertItem(item);
if (result.success == false)
return result;
ts.Complete();
}
catch (Exception)
{
ts.dispose();
return result;
}
}
return result;
}
视为服务器错误,并且始终会针对所述服务器错误 dispose
返回已修复的错误消息。
尽管后端按照我希望的方式工作,但我更希望 An internal error occurred during your request
不会被捕获为服务器错误并导致前端显示上述错误消息。
下面将包含记录的错误消息。
dispose
我怀疑这可能不仅仅是 ERROR 2021-04-26 14:34:04,260 [::1] [Chrome90] [20] Abp.WebApi.ExceptionHandling.AbpApiExceptionFilterattribute - The transaction has aborted.
System.Transactions.TransactionAbortedException: The transaction has aborted.
at System.Transactions.TransactionStateAborted.BeginCommit(InternalTransaction tx,Boolean asyncCommit,AsyncCallback asyncCallback,Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.Internaldispose()
at System.Transactions.TransactionScope.dispose()
at Abp.EntityFramework.Uow.TransactionScopeEfTransactionStrategy.Commit()
at Abp.EntityFramework.Uow.EfUnitOfWork.CompleteUow()
at Abp.Domain.Uow.UnitOfWorkBase.Complete()
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation,UnitOfWorkOptions options)
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation,UnitOfWorkOptions options)
at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Auditing.AuditingInterceptor.PerformSyncAuditing(IInvocation invocation,AuditInfo auditInfo)
at Abp.Auditing.AuditingInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Abp.Runtime.Validation.Interception.ValidationInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.XXXAppServiceProxy.TriTransaction(TransactItem[] item)
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptiondispatchInfo.Throw()
at Abp.WebApi.Controllers.Dynamic.Interceptors.AbpDynamicApiControllerInterceptor`1.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.DynamicApiController`1Proxy_4.TriTransaction(TransactItem[] item)
at lambda_method(Closure,Object,Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__displayClass6_2.<GetExecutor>b__2(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__17`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__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.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__17`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 Abp.WebApi.Uow.AbpApiUowFilter.<ExecuteActionFilterasync>d__6.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__17`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 Abp.WebApi.Validation.AbpApiValidationFilter.<ExecuteActionFilterasync>d__5.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__17`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 Abp.WebApi.Auditing.AbpApiAuditFilter.<ExecuteActionFilterasync>d__4.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__17`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__5.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 Abp.WebApi.Security.AntiForgery.AbpAntiForgeryApiFilter.<ExecuteAuthorizationFilterasync>d__10.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__17`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 Abp.WebApi.Authorization.AbpApiAuthorizefilter.<ExecuteAuthorizationFilterasync>d__7.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__17`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.AuthenticationFilterResult.<ExecuteAsync>d__5.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__6.MoveNext()
被捕获为错误的事实,也可能完全是其他原因,但我对此没有足够的了解,想知道是否有任何错误解决前端总是显示 dispose
错误消息的问题的方法,每当有意处理事务时。
解决方法
您的问题是您调用 Dispose
两次,您永远不需要手动调用 Dispose
,这就是 using
语句的用途。 using (...)
基本上只是 try/finally 块的一些 syntactic sugar。所以这个:
using (var foo = new Foo())
{
foo.SayHello();
}
被编译为
Foo foo = new Foo();
try
{
foo.SayHello();
}
finally
{
if (foo != null)
{
((IDisposable)foo).Dispose();
}
}
意味着你的代码被编译为
CUDResult result = new CUDResult();
TransactionScope ts = new TransactionScope();
try
{
try
{
result = InsertItem(item);
if (!result.success) // instead of result.success == false
return result;
ts.Complete();
}
catch (Exception)
{
ts.Dispose();
return result;
}
}
finally
{
if (ts != null)
{
((IDisposable)ts).Dispose();
}
}
return result;
很明显,当捕获到异常时,您将处理 ts
两次
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。