【问题标题】:What does "Resetting the connection" mean? System.Data.SqlClient.SqlException (0x80131904)“重置连接”是什么意思? System.Data.SqlClient.SqlException (0x80131904)
【发布时间】:2020-09-03 10:42:52
【问题描述】:

我知道这有点含糊,但我无法确定问题所在。

当我对本地数据库运行一些代码时,它运行良好。当我使用远程数据库时出现错误。 它发生在程序执行的中间。 DBup 升级运行,然后手动查询失败,出现以下异常:

System.Data.SqlClient.SqlException (0x80131904):重置连接会导致与初始登录不同的状态。登录失败。 用户“sa”登录失败。

我正在使用new SqlConnection() 手动创建SqlConnection,我也在使用DbUp

我不确定我做错了什么。也不是从哪里开始调试这个。 ConnectionString 不变,我一直使用sa 连接数据库。

一个很好的问题是“重置连接”是什么意思?我是怎么做到的?

【问题讨论】:

  • 如果数据库连接到服务器,切勿在连接字符串中使用 AttachDB (localdb) 属性(删除)。服务器拥有 mdf 数据库文件,不允许用户直接访问该文件。您必须通过服务器和实例连接到数据库。为了调试,我使用 SQL Server Management Studio。 SSMS 登录窗口将显示应在 c# 连接字符串中使用的服务器和实例名称。登录窗口还显示 Window Credental,它在连接字符串中等效于 Integrated Security = true 并使用用户(或组)窗口凭据。
  • @Igor 解决方案是使用普通的 ado.net,我正在这样做。
  • @jdweng 我没有使用 (localdb) 它只是一个在 localhost 上运行的 SQLServer 实例
  • 要使本地计算机和远程计算机的连接正常工作,必须具有相同的凭据。通常我会将数据库凭据设置为 Window 用户组,然后将用户放入该组。必须在本地和远程计算机上分配组。公司通常具有可用于数据库凭据的组策略设置。

标签: c# .net sql-server sqlconnection dbup


【解决方案1】:

经过几个小时的反复试验,我得到了重现错误的最小代码段

string dbName = "TESTDB";
Run("master", $"CREATE DATABASE [{dbName}]");
Run(dbName, $"ALTER DATABASE [{dbName}] COLLATE Latin1_General_100_CI_AS");
Run(dbName, "PRINT 'HELLO'");

void Run(string catalog, string script)
{
    var cnxStr = new SqlConnectionStringBuilder
    {
        DataSource = serverAndInstance,
        UserID = user,
        Password = password,
        InitialCatalog = catalog
    };

    using var cn = new SqlConnection(cnxStr.ToString());
    using var cm = cn.CreateCommand();
    cn.Open();
    cm.CommandText = script;
    cm.ExecuteNonQuery();
}

完整的堆栈跟踪是

Unhandled Exception: System.Data.SqlClient.SqlException: Resetting the connection results in a different state than the initial login. The login fails.
Login failed for user 'user'.
Cannot continue the execution because the session is in the kill state.
A severe error occurred on the current command.  The results, if any, should be discarded.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
...

如果我将第一个 Run(dbName... 更改为 Run("master"... 它运行良好。 所以它与在同一个数据库的上下文中运行ALTER DATABASE有关

【讨论】:

【解决方案2】:

这不是我的问题的答案,但我通过不处置 SqlConnection 而是重复使用它来解决这个问题。

我还是不明白这个问题

【讨论】:

  • 这几乎和使用sa 一样糟糕。您现在在您使用的任何表上累积锁,阻止其他连接。您没有发布任何代码,甚至没有发布完整的异常,因此无法理解问题
  • 这显示的一件事是你用来创建连接的代码做了一些奇怪的事情。
  • 这两个连接字符串是什么样的?您使用哪些 SQL Server 版本? ADO.NET 汇集连接并重用它们。每次关闭/处理连接时,它都会重置并放回池中。如果使用 Windows 身份验证,则按连接字符串和 Windows 帐户汇集连接。有关重置连接的错误表明池混淆了(不太可能,否则您会看到 很多 类似的问题)或远程服务器中的某些内容发生了变化。也许不同的数据库?切换到单用户模式?用户实例数据库?
  • @PanagiotisKanavos 感谢 cmets。我没有发布代码,因为它是一个很大的代码库,我不确定是什么导致了这个问题。创建连接的代码很简单 new SqlConnection(connectionString);然后是 Open()
  • 我建议再次阅读可能重复的内容,因为您似乎在做同样的事情——创建一个新数据库。副本使用 EF 迁移,您使用的是 DbUp。这意味着与同一服务器的连接最终可能会尝试从一个阶段到下一阶段登录到不同的数据库。
猜你喜欢
  • 2014-11-25
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2010-12-01
  • 1970-01-01
  • 2019-07-16
相关资源
最近更新 更多