首先要說明的是串連數是有限制的:
代碼如下:
- for (int i = 0; i < 10000; i++)
- {
- SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;
- AttachDbFilename=""E:\DB\NORTHWND.mdf"";
- Integrated Security=True;Connect Timeout=30;User Instance=True");
-
- conn.Open();
- Console.WriteLine("開啟了{0}個串連", i);
- }
運行結果如下:
過一會就會提示開啟連線逾時了:
可以看到資料庫連接時有限制的,如果串連不關閉,而且使用的人比較多,那麼系統很快就down掉了。
但是有時候由於某些原因應用程式可能只是幾個人使用,所以就有人設計了:
在應用程式啟動的時候開啟資料庫連接,在應用程式關閉的時候關閉資料庫連接
那麼使用這種方式有什麼問題呢?
首先假設有一張表Nums,表定義如下:
Main代碼如下:
- SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;
- AttachDbFilename=""E:\DB\NORTHWND.mdf"";
- Integrated Security=True;Connect Timeout=30;User Instance=True");
- conn.Open();
- Parallel.For(1, 9999, (id) =>
- {
- ExecuteCommand(conn, id);
- });
就是從1到9999開始執行ExecuteCommand
ExecuteCommand代碼如下:
- private static void ExecuteCommand(SqlConnection conn, int id)
- {
- Console.WriteLine("正在執行." + id);
-
- Thread.Sleep(100);
-
- SqlCommand cmd = new SqlCommand(
- string.Format("Insert into Nums values('{0}') ", id), conn);
-
- cmd.ExecuteNonQuery();
- }
運行:
可以看到ExecuteNonQuery方法拋出了異常,原因是串連處於關閉狀態。
可是我們的串連一直都是open著的啊,並沒有調用close,dispose之類的方法啊。
於是在ExecuteCommand前面增加判斷條件:
- if (conn.State != System.Data.ConnectionState.Open)
- conn.Open();
再次運行:
可以看到還是會出現串連已關閉的問題。你知道什麼原因嗎?
這裡是由於多線程環境引起的。所以需要加鎖。
- private static object syncObj = new object();
- private static void ExecuteCommand(SqlConnection conn, int id)
- {
- lock (syncObj)
- {
- if (conn.State != System.Data.ConnectionState.Open)
- conn.Open();
- Console.WriteLine("正在執行.." + id);
- Thread.Sleep(100);
- SqlCommand cmd = new SqlCommand(
- string.Format("Insert into Nums values('{0}') ", id), conn);
- cmd.ExecuteNonQuery();
- }
- }
再次運行:可以發現基本沒問題了.
修改Parallel.For的最大值上限,要測試下是否可以長期執行了。
- Parallel.For(1, Int32.MaxValue, (id) =>
- {
- ExecuteCommand(conn, id);
- });
一天測試下來,沒出現任何問題。
結論:對於某些只有幾個人使用的應用程式,可以不關閉資料庫連接,但是在寫代碼的時候最好要加上串連是否開啟的判斷。