none
【C#】SQL连接与会话的疑惑? RRS feed

  • 问题

  • 请先看代码:

    SqlConnection con = new SqlConnection(...);
    SqlCommand sc = new SqlCommand();
    con.Open();
    sc.Connection = con;
    sc.CommandText = "create table #t (test varchar(20))";
    sc.ExecuteNonQuery();
    sc = new SqlCommand();
    sc.Connection = con;
    sc.CommandText = "create table #t (test varchar(20))";
    sc.ExecuteNonQuery();

    运行这段代码会报【数据库已存在名为#t的临时表】,说明两次ExecuteNonQuery()是处于同一会话。那么请问:

    一个SqlConnection实例Open()后,是否所有使用该连接的SqlCommand实例,不管有多少份,也不管是通过ExecuteScalar()、ExecuteReader()还是ExecuteNonQuery()执行语句,它们都是共用一个会话(除非连接关闭并重开过),一定是这样吗?有例外吗?


    2012年6月7日 1:02

答案

全部回复

  • 其实 这里面还涉及到一个 连接池的概念

    一般情况来说你说的没问题。但是连接池会复用连接(spid),这样可能会出现即时你打开,关闭再打开,但是spid还是一样。


    family as water

    • 已标记为答案 ahdung_AI 2012年6月8日 4:55
    2012年6月7日 6:23
  • 感谢Stone回复,那如果不使用连接池,有没有办法可以实现即便连接中断再打开,还能进行之前那个会话吗?

    另外还有一个问题想请教:我自己的一个类,在构造函数时就打开一个连接,类中的所有涉及执行SQL命令的方法都共用该连接,所以没有一个方法会去关闭连接,那么请问我需要显式地定义析构函数,并在其中关闭连接吗?还是默认的析构函数会打点一切,无需定义?

    2012年6月8日 1:52
  • 刚刚做了实验,发现程序关闭后连接也会自行关闭,但不知道是CLR打点的还是类的默认析构函数打点的。
    2012年6月8日 2:02
  • 我想我找到答案了:

    http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqldatareader.close(v=vs.80).aspx

    根据这篇文章的警告部分所述,如果类没有使用非托管资源就无需显式定义析构函数。

    2012年6月8日 4:55