TransactionScope不能与linux上的async / await方法一起使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TransactionScope不能与linux上的async / await方法一起使用相关的知识,希望对你有一定的参考价值。
我正在开发一个基于asp.net核心mvc的博客项目,并尝试在ubuntu 16.04 LTS x86-64上部署我的项目。
在将对象插入sql server时使用transactionScope和dapper时遇到了空引用异常。
SQL Server版本为:12.0.4100.1在Windows 2012SP1系统上运行。并且代码在Windows 10(OS Build 17074.1002)上正常运行。但是当我将项目部署到Ubuntu时,它会抛出空引用异常。
异常细节如下:
{System.NullReferenceException:对象引用未设置为对象的实例。 System.Data.ProviderBase.DbConnectionPool.DeactivateObject(DbConnectionInternal obj)处于System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject,DbConnectionFactory connectionFactory)的System.Data.ProviderBase.DbConnectionPool.PutObject(DbConnectionInternal obj,Object owningObject)处的System.Data.ProviderBase.DbConnectionPool.DeactivateObject(DbConnectionInternal obj) System.Data.SqlClction.SqlConnection.Close()中的.Data.SqlClient.SqlConnection.CloseInnerConnection()位于Dapper.SqlMapper.d__64 1.MoveNext()位于C: projects dapper Dapper SqlMapper.Async.cs:line 1191 ---抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices上的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd上的.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()at /anome.NiChiJou.Repository.Dapper.BaseDapperRepository 1.d__22.MoveNext()in /home/alex/Documents/Github/Autyan.NiChiJou/src/Autyan.NiChiJou。 Repository.Dapper / BaseDapperRepository.cs:第167行---抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的任务任务(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()at /anome.NiChiJou.Repository.Dapper.LongKeyDapperRepository 1.d__1.MoveNext()in /home/alex/Documents/Github/Autyan.NiChiJou/src/Autyan.NiChiJou。 Repository.Dapper / LongKeyDapperRepository.cs:第23行---从抛出异常的先前位置开始的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd上的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的任务任务(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()at /home/alex/Documents/Github/Autyan.NiChiJou/src/Autyan.NiChiJou.Service中的Autyan.NiChiJou.Service.Blog.ArticleService.d__10.MoveNext() .Blog / ArticleService.cs:第39行}
抛出异常的代码是这样的:
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
var create = await ArticleRepo.InsertAsync(article);
if (create <= 0)
{
return Failed<Article>("create article failed");
}
create = await ContentRepo.InsertAsync(new ArticleContent
{
ArticleId = create,
Content = content
});
if (create <= 0)
{
return Failed<Article>("create articleContent failed");
}
scope.Complete();
}
我试图删除transactionScope,之后,我的代码运行得很好
新代码如下:
var create = await ArticleRepo.InsertAsync(article);
if (create <= 0)
{
return Failed<Article>("create article failed");
}
create = await ContentRepo.InsertAsync(new ArticleContent
{
ArticleId = create,
Content = content
});
if (create <= 0)
{
return Failed<Article>("create articleContent failed");
}
我用错误的方式使用trancsationScope吗?或者它只是来自dotnet核心本身的错误?
这是因为当等待结束时,分配给继续执行await之后的语句的线程已经丢失了原始执行线程所具有的事务上下文。
将您的Txn范围定义为:
using (var scope = new TransactionScope(..., TransactionScopeAsyncFlowOption.Enabled))
以上是关于TransactionScope不能与linux上的async / await方法一起使用的主要内容,如果未能解决你的问题,请参考以下文章
TransactionScope 与 SQLite 内存数据库和 NHibernate
将 TransactionScope 与实体框架 6 一起使用
.Net Oracle TransactionScope的使用