SQL服务停止后,Conn.Open()仍然有效

时间:2010-11-16 03:13:48

标签: sql-server database-connection issue-tracking

我遇到了sql server 2005 SP2的问题,我创建了一个Windows窗体并在其上面有一个按钮,并执行以下步骤:

  1. 确保Sql服务正在运行,然后单击按钮,一切正常
  2. 停止Sql服务,然后再次点击该按钮,在我的机器上, LINE 1 的代码没有异常, LINE 2 发生异常,这是例外信息:
  3. 消息:将请求发送到服务器时发生传输级错误。 (提供者:共享内存提供者,错误:0 - 管道的另一端没有进程。)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    
    namespace ReconnectSQL
    {
        public partial class Form1 : Form
        {
    
            private string m_ConnectionString = @"Server=(local); Database=testDB; User ID=sa; Password=admins; Connection Timeout=15";
    
            public Form1()
            {
                InitializeComponent();
            }
    
            /// <summary>
            /// 
            /// </summary>
            public DataTable GetByFillDataTable()
            {
                try
                {
                    SqlCommand cmd = new SqlCommand("getalldata");
                    cmd.CommandType = CommandType.StoredProcedure;
    
                    DataTable dt = this.GetDataTable(cmd);
                    return dt;
                }
                catch
                {
                    throw;
                }
            }
    
    
            #region common funcs
            /// <summary>
            /// 
            /// </summary>
            /// <param name="cmd"></param>
            /// <returns></returns>
            private DataTable GetDataTable(SqlCommand cmd)
            {
                DataTable dt = new DataTable();
    
                using (SqlConnection conn = new SqlConnection(this.m_ConnectionString))
                {
                    try
                    {
                        conn.Open();  // LINE 1
                    }
                    catch (Exception eX)
                    {
                        throw;
                    }
    
                    using (SqlDataAdapter adapter = new SqlDataAdapter())
                    {
                        try
                        {
                            cmd.Connection = conn;
                            cmd.CommandTimeout = conn.ConnectionTimeout;
                            adapter.SelectCommand = cmd;
                            adapter.Fill(dt);  // LINE 2
                        }
                        catch (Exception eX)
                        {
                            throw;
                        }
                    }
                }
    
                return dt;
            }
    
            #endregion       
    
            private void button2_Click(object sender, EventArgs e)
            {
    
                try
                {
                    DataTable dt = GetByFillDataTable();
                    listBox1.Items.Add("GetByFillDataTable is called without exceptions!");
                }
                catch (Exception ex)
                {
                    listBox1.Items.Add(ex.Message);
                }            }
        }
    }
    

    详细的异常信息:

    -       [System.Data.SqlClient.SqlException]    {"A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)"} System.Data.SqlClient.SqlException
    +       base    {"A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)"} System.Data.Common.DbException {System.Data.SqlClient.SqlException}
            Class   20  byte
    +       Errors  {System.Data.SqlClient.SqlErrorCollection}  System.Data.SqlClient.SqlErrorCollection
            LineNumber  0   int
            Number  233 int
            Procedure   null    string
            Server  "(local)"   string
            Source  ".Net SqlClient Data Provider"  string
            State   0   byte
    

    栈跟踪

    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
       at System.Data.SqlClient.TdsParserStateObject.WriteSni()
       at System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode)
       at System.Data.SqlClient.TdsParserStateObject.ExecuteFlush()
       at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc)
       at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
       at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
       at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
       at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
       at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
       at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
       at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
       at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
       at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
       at ReconnectSQL.Form1.GetDataTable(SqlCommand cmd) in E:\_public_\sqlFail\ReconnectSQL\ReconnectSQL\Form1.cs:line 138
    

1 个答案:

答案 0 :(得分:1)

经过一些调查,似乎连接池中仍然存在连接,即使sql已停止,因此在启动sql并调用conn.Open()后,它从池中获取应该无效的连接对象,然后SqlDataAdapter.Fill导致异常

http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/99963999-a59b-4614-a1b9-869c6dff921e