C# 事务结果用作参数时出现超时错误
我有以下使用SqlTransaction的代码C# 事务结果用作参数时出现超时错误,c#,concurrency,ado.net,transactions,C#,Concurrency,Ado.net,Transactions,我有以下使用SqlTransaction的代码 string connectionString = ConfigurationManager.AppSettings["ConnectionString"]; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); SqlTransaction transaction = connection.BeginT
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
int logID = HelperClass.InsertException(connection, 1, DateTime.Now, "Y", "test", "test", 1, 1, transaction);
LogSearch logSearch = new LogSearch();
logSearch.LogID = 258;
Collection<Log> logs = HelperClass.GetLogs(logSearch, connectionString);
}
我猜这是因为
HelperClass.GetLogs(logSearch,connectionString)代码>实例化事务范围外的新连接:
您可以根据自己的意愿:
- 让助手类接受保存事务的连接对象,而不是连接字符串
- 或者将
“从应用程序中选择*,其中应用程序中的应用程序中的应用程序id=@Application\u-EX\u-id”
替换为“从应用程序中的应用程序中选择*,其中应用程序中的应用程序id=@Application\u-EX\u-id”
请注意,第二种情况有时会返回不正确的值,并且不会返回您当前在事务中插入的值
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
int logID = HelperClass.InsertException(connection, 1, DateTime.Now, "Y", "test", "test", 1, 1, transaction);
LogSearch logSearch = new LogSearch();
logSearch.LogID = 258;
Collection<Log> logs = HelperClass.GetLogs(logSearch, connectionString);
}
希望这会有所帮助我想这是因为HelperClass.GetLogs(logSearch,connectionString)代码>实例化事务范围外的新连接:
您可以根据自己的意愿:
- 让助手类接受保存事务的连接对象,而不是连接字符串
- 或者将
“从应用程序中选择*,其中应用程序中的应用程序中的应用程序id=@Application\u-EX\u-id”
替换为“从应用程序中的应用程序中选择*,其中应用程序中的应用程序id=@Application\u-EX\u-id”
请注意,第二种情况有时会返回不正确的值,并且不会返回您当前在事务中插入的值
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
int logID = HelperClass.InsertException(connection, 1, DateTime.Now, "Y", "test", "test", 1, 1, transaction);
LogSearch logSearch = new LogSearch();
logSearch.LogID = 258;
Collection<Log> logs = HelperClass.GetLogs(logSearch, connectionString);
}
希望这能对你的问题有所帮助
当我传递logID(InsertException()的结果)时,为什么会出现异常
请解释为什么我将硬编码值作为LogID传递时没有异常
答复
当使用事务插入新记录时,这意味着在您自己提交事务之前,新记录不会最终提交。在此之前,新记录将被锁定,这意味着任何涉及该新记录的查询都将被挂起,直到出现超时。在您的情况下,对方法GetLogs的调用在事务仍在运行时执行,该方法搜索新插入的record-id。由于行已锁定,因此GetLogs调用将等待超时发生,这将导致超时异常
对于硬编码的值,对GetLogs的调用将搜索具有相应id的现有记录。由于您正在搜索PK值,SQL不必搜索所有行,因为它是PK。因此,现有行将在单独的事务中找到并返回,因为这些事务在它们所接触的数据中不重叠
假设您的方法GetLogs在另一列上搜索表,一个非pk列(例如application_message),那么必须读取整个表才能找到一行(或多行),其中包含application_message的相应值。这将导致查询始终接触新插入的锁定行,然后使用硬编码(应用程序消息)值,您将获得超时异常。我添加这些只是为了澄清锁定,以及SQL何时需要或不需要接触锁定的行
希望这有帮助。问题
当我传递logID(InsertException()的结果)时,为什么会出现异常
请解释为什么我将硬编码值作为LogID传递时没有异常
答复
当使用事务插入新记录时,这意味着在您自己提交事务之前,新记录不会最终提交。在此之前,新记录将被锁定,这意味着任何涉及该新记录的查询都将被挂起,直到出现超时。在您的情况下,对方法GetLogs的调用在事务仍在运行时执行,该方法搜索新插入的record-id。由于行已锁定,因此GetLogs调用将等待超时发生,这将导致超时异常
对于硬编码的值,对GetLogs的调用将搜索具有相应id的现有记录。由于您正在搜索PK值,SQL不必搜索所有行,因为它是PK。因此,现有行将在单独的事务中找到并返回,因为这些事务在它们所接触的数据中不重叠
假设您的方法GetLogs在另一列上搜索表,一个非pk列(例如application_message),那么必须读取整个表才能找到一行(或多行),其中包含application_message的相应值。这将导致查询始终接触新插入的锁定行,然后使用硬编码(应用程序消息)值,您将获得超时异常。我添加这些只是为了澄清锁定,以及SQL何时需要或不需要接触锁定的行
希望这能有所帮助。我不明白为什么它会返回异常。在第一次调用中未提交数据。那很好。但是为什么会出现异常呢?因为在事务完成之前,对应的行都会被锁定,从而防止查询表。您的助手等待一个永远不会出现的锁释放(因为释放应该在助手成功运行之后发生)请解释为什么当我将硬编码值传递为LogID@Lijo:这是因为系统能够计算硬编码值行与当前插入的值之间没有冲突。因此,它可以安全地返回硬编码的值行。无论您提交还是回滚事务,这些都是相同的。这是一个行级锁。@Lijo您可以从阅读事务隔离级别开始:我不明白为什么它会返回异常。在第一次调用中未提交数据。那很好。但是为什么会出现异常呢?因为相应的行在事务处理之前是锁定的