Asp.net 为什么';t TransactionScope为我的以下SQL命令启动事务
我在ASP.NET操作开始时为Asp.net 为什么';t TransactionScope为我的以下SQL命令启动事务,asp.net,.net,sql-server,Asp.net,.net,Sql Server,我在ASP.NET操作开始时为事务范围设置了一个using块。在某个地方,我执行一个函数,该函数既为SqlCommand创建一个using块,又为SqlConnection创建一个using块 重复使用功能时,命令和连接块打开和关闭,但所有w/i都使用TransactionScopeusing块。最后我调用了scope.Complete(),当使用block离开TransactionScope时,我得到一个异常,表示没有启动可以提交的事务。在调试过程中,我发现实际上所有的数据库调用都是在没有事务
事务范围设置了一个using块。在某个地方,我执行一个函数,该函数既为SqlCommand
创建一个using块,又为SqlConnection
创建一个using块
重复使用功能时,命令和连接块打开和关闭,但所有w/i都使用TransactionScope
using块。最后我调用了scope.Complete()
,当使用block离开TransactionScope
时,我得到一个异常,表示没有启动可以提交的事务。在调试过程中,我发现实际上所有的数据库调用都是在没有事务的情况下进行的
根据文档,它看起来像是事务范围的生成,应该是事务的生成,或者至少在我第一次打开任何数据库连接时,事务应该开始,因为它是事务范围块。然而事实并非如此,我不确定为什么会这样
事实上,我有一次工作得很好,然后突然,它不工作了。所以我做了一些事情导致了它,但我不知道它是什么,因为这一部分是在很久以前完成的
下面是一些代码:
启动transactionScope
using (TransactionScope transactionScope = new TransactionScope())
{
try
{
LegacyDataManager.Start();
//*******************Replace W/ Controller Logic*********************
ViewBag.Message = "Finish";
...
...
...
LegacyDataManager.Commit();
transactionScope.Complete();
}
finally
{
LegacyDataManager.Stop();
}
}
调用执行数据库更新的代码
var theApproval = LegacyDataManager.PrepareForUpdate(Constants.ObjectApproval, row["objectInstance"].ToString(), row["sourceServer"].ToString());
theApproval.write("approvalaction", Request.Form[val].ToString().Substring(0, 1));
theApproval.write("approvaldate", Data_Legacy.getAodDateTimeNow());
theApproval.saveObject();
数据库查询执行
Data.executeSP("sp_Object_InsertData", SearchNew.generateSQLParameterString("ObjectType", "ObjectInstance", "Parameter", "ParameterValue", "SourceServer"),
SearchNew.generateSQLParameterString(
ObjectType,
ObjectInstance.ToString(),
theNametext,
Regex.Replace(thetheVal, @"\'", "\'\'").Trim(),
SourceServer));
public static DataTable executeSP(string storedProc, SqlParameter[] parms = null, bool gatherParams = true, int commandTimeout = 0)
{
using (SqlCommand cmd = new SqlCommand())
{
if (commandTimeout != 0)
{
cmd.CommandTimeout = commandTimeout;
}
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = storedProc;
handleParameters(cmd.Parameters, storedProc, parms, gatherParams);
using (SqlConnection conn = Data.getConnection("AOD"))
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
var da = new SqlDataAdapter();
var dt = new DataTable();
da.SelectCommand = cmd;
da.Fill(dt);
return dt;
}
}
}
提前谢谢你的建议
好消息是,这可以删除,但坏消息是,它创建了一个恼人的编程环境,在此环境中,此系统所基于的XML数据文件不会在错误期间得到更新,但镜像到的更新SQL数据会被保留。。。不要问为什么会这样。。。就是这样。显然,我在运行存储过程的函数周围添加了一个try/catch块,因为传入的数据有时需要函数,有时不需要(因此会失败,从而导致try-catch)。不幸的是,当db调用失败时,与TransactionScope关联的事务被丢弃,try-catch使程序继续运行
在决定是否执行存储过程之前,我删除了try-catch块,并通过对传递到函数中的数据进行检查来替换它,现在它再次正常运行
TL;DR-检查是否有任何数据库调用在使用transactionScope时失败,因为这可能会导致事务中断。您的TL;DR不正确-try..catch在TransactionScope
中没有问题。说应该避免使用它们是不准确的,因为有充分的理由使用它们。@Fermin当潜在的可怕问题与完全使用try-catch直接相关时,你怎么能这么说呢?使用try..catch insideTransactionScope
是完全正确的,这就是为什么我说这是不正确的。您的一个具体问题与您如何实现它们有关。作为比较,我在将字符串转换为DateTime
时遇到了问题,但我不建议使用TL;DR:在使用字符串时尽量避免使用DateTime
。我已经考虑过这一点,现在认为问题与Try-catch中的内容有关,而不是Try-catch本身。我在包含try-catch块的函数中执行一个存储过程,该存储过程由于传递给它的数据而失败。我假设db端的错误与transactionScope的事务丢失之间存在某种关联。不管怎样,试捕让它继续按预期进行。我将根据实际情况更改原始消息。