我现在已经开展了大约一天半的工作,并在网上搜索了大量的博客和帮助文章。我发现了几个与此错误相关的SO问题,但我认为它们并不适用于我的情况(或者在某些情况下,遗憾的是,我无法理解它们的实现:P)。我不确定我能够很好地描述这个问题......但是这里有:
我们有一个.NET应用程序来跟踪我们的资源。有一个导出功能可以将资源复制到时间跟踪系统和计费系统;这将访问链接到时间和计费数据库的存储过程。
我最近将计费系统数据库移动到新服务器(原始服务器:Server 2003 SP2,SQL 2005;新服务器:Server 2008 R2,SQL 2008 R2)。我有一个指向2008数据库的链接服务器设置。我更新了存储过程以指向2008服务器,然后我收到有关MSDTC和RPC的错误(http://www.safnet.com/writing/tech/archives/2007/06/server_myserver.html)。我在链接服务器上启用了“rpc / rpc out”并将MSDTC设置为允许网络访问(如下所示:http://www.sqlwebpedia.com/content/msdtc-troubleshooting)。
现在,当我尝试运行导出功能时,我得到了上述内容:“此SqlTransaction已完成;它已不再可用。”对我来说似乎很奇怪的是,当我刚刚运行存储过程(来自SSMS)时,它表示它已成功完成。
有没有人见过这个?我在配置中遗漏了什么吗?我继续浏览相同的页面,我发现的唯一一件事是我在进行MSDTC更改后没有重新启动(在此处提到:http://social.msdn.microsoft.com/forums/en-US/adodotnetdataproviders/thread/7172223f-acbe-4472-8cdf-feec80fd2e64/)。
我可以发布部分或全部存储过程,如果有帮助的话......请告诉我。
答案 0 :(得分:41)
我认为此错误消息是由于“僵尸交易”造成的。
查找transacton提交两次的可能区域(或回滚两次,或回滚并提交等)。 SP已经提交后,.Net代码是否提交了事务? .Net代码是否在遇到错误时回滚它,然后尝试在catch(或finally)子句中再次回滚它?
可能在旧服务器上没有遇到错误情况,因此错误的“双回滚”代码从未被命中。也许你现在遇到新服务器上 某些配置错误的情况,现在错误代码被异常处理命中了。
你可以调试错误代码吗?你有堆栈跟踪吗?
答案 1 :(得分:6)
我在最近重新构建一个新的连接管理器后得到了这个。新例程接受了一个事务,因此它可以作为批处理的一部分运行,问题在于使用块:
public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
using (transaction.Connection)
{
using (transaction)
{
return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
}
}
}
看起来外部使用正在关闭底层连接,因此任何提交或回滚事务的尝试都会抛出消息"This SqlTransaction has completed; it is no longer usable."
我删除了使用添加了覆盖测试,问题就消失了。
public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
}
检查在事务上下文中可能正在关闭连接的任何内容。
答案 2 :(得分:4)
我有同样的问题。发生此错误是因为连接池。当存在两个或多个用户访问系统时,连接池也重用连接和转换。如果第一个用户执行commit ou rollback,则事务不再可用。
答案 3 :(得分:3)
我最近遇到过类似的情况。要在任何VS IDE版本中进行调试,请从Debug(Ctrl + D,E)打开异常 - 选中“Thrown”列的所有复选框,然后以调试模式运行应用程序。我已经意识到其中一个表未在新数据库中正确导入,因此内部Sql异常会终止连接,从而导致此错误。
故事的要点是,如果以前工作的代码在新数据库上返回此错误,这可能是数据库模式缺失的问题,通过上面的调试提示实现,
希望它有帮助, HydTechie
答案 4 :(得分:3)
在我的情况下,问题是交易中包含的一个查询引发了异常,即使异常是&#34;优雅地&#34;处理后,它仍然设法回滚整个交易。
我的伪代码就像:
var transaction = connection.BeginTransaction();
for(all the lines in a file)
{
try{
InsertLineInTable(); // INSERT statement might fail and throw an exception
}
catch {
// notify the user about the error on line x and continue
}
}
// Commit and Rollback will fail if one of the queries
// in InsertLineInTable threw an exception
if(CheckTableForErrors())
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
答案 5 :(得分:1)
还要检查从.NET应用程序执行的任何长时间运行的进程。例如,您可能正在调用没有足够时间完成的存储过程或查询,这些过程可以在日志中显示为:
执行超时已过期。超时时间过去之前 完成操作或服务器没有响应。
检查命令超时设置 尝试运行跟踪(探查器)并查看数据库端发生的情况......
答案 6 :(得分:1)
遇到了完全相同的问题,只是找不到正确的解决方案。 希望这对某人有帮助。
我有一个带有EF Core的.NET Core 3.1 WebApi。在同时收到多个呼叫时,应用程序试图同时将更改添加并保存到数据库。
在我的情况下,问题在于保存数据的表没有主键集。
当从应用程序迁移时,以某种方式将模型中的ID作为主键时,EF Core以某种方式丢失了。
我通过打开SQL事件探查器发现所有事务都已成功(从应用程序)提交到数据库,但是仅创建了一个新行,从而发现了问题。探查器还显示出某种类型的死锁正在发生,但在探查器的跟踪日志中我看不到更多。 在进一步检查中,我注意到“ Id”列中缺少主键标识符。
我从应用程序中获得的异常是:
此SqlTransaction具有 完成它不再可用。
和/或
引发了一个异常,该异常可能是由于瞬态 失败。考虑通过添加以下方式启用瞬态错误恢复能力 将'EnableRetryOnFailure()'转到'UseSqlServer'调用。
答案 7 :(得分:0)
这是一种检测Zombie交易的方法
SqlTransaction trans = connection.BeginTransaction();
//some db calls here
if (trans.Connection != null) //Detecting zombie transaction
{
trans.Commit();
}
反编译SqlTransaction类,您将看到以下内容
public SqlConnection Connection
{
get
{
if (this.IsZombied)
return (SqlConnection) null;
return this._connection;
}
}
我注意到如果连接关闭,transOP将变成僵尸,因此不能Commit
。
对于我的情况,这是因为我在Commit()
块中有finally
,而连接在try
块中。这种安排导致连接被处理和垃圾收集。解决方案是将Commit
放在try
块中。
答案 8 :(得分:0)
就我而言,在同一try catch块中提交事务后,我有一些代码。 错误可能导致执行捕获到包含事务回滚的块。 它将显示类似的错误。例如,看下面的代码结构:
SqlTransaction trans = null;
try{
trans = Con.BeginTransaction();
// your codes
trans.Commit();
//your codes having errors
}
catch(Exception ex)
{
trans.Rollback(); //transaction roll back
// error message
}
finally
{
// connection close
}
希望它将对某人有所帮助:)
答案 9 :(得分:0)
就其价值而言,我已经在以前的工作代码中遇到了这个问题。我在调试测试的触发器中添加了 SELECT 语句,但忘记删除它们。当其他东西输出到“网格”时,实体框架/MVC 效果不佳。请务必检查是否存在任何恶意查询并将其删除。