重用SqlConnection的最佳实践

我来自Java经验,我试图从C#开始。 我已经阅读了SqlConnection SqlCommand SqlDataReader IDisposable ,我可以理解连接到数据库的最佳做法是在自己的using块中包装SqlConnectionSqlCommandSqlDataReader

但在Java中,我们使用将连接封装到工厂方法中,仅创建一次,并将其重用于所有查询,甚至是multithreading查询。 仅为每个查询创建语句和结果集,并尽快关闭。

是不是为每个查询创建一个新的SqlConnection有点矫枉过正? 不能重复使用吗?

创建类的新实例SqlConnection不会创建到SQL Server的新网络连接,而是租用现有连接(或创建新连接)。 .NET为您处理物理连接池。

完成连接后(通过它可以发送多个查询)只需要Close()Dispose() (或者最好使用using{}块)。

缓存SqlConnection类的实例没有必要,也没有好的做法。

MS SQL服务器管理它自己的连接池中的连接,并且它们实际上没有被处理掉。 但它们已关闭,因此您可以最小化网络流量并释放与服务器的可用连接。

另外你应该注意,如果你使用的是Linq-To-SQL,数据上下文在被处理之前不会释放连接,所以我建议你只使用已经工作的代码,不要试图自己优化它。

正如VMAtm所说,.net汇集了它自己的连接,所以重新创建它们是完全可以的。 因此,我通常会像这样编写整个过程的包装器。

  public static void RunWithOpenSqlConnection(string connectionString, Action connectionCallBack) { SqlConnection conn = null; try { conn = new SqlConnection(connectionString); connectionCallBack(conn); } catch (Exception ex) { //Log Error Here } finally { if (conn != null) conn.Dispose(); //will close the connection } } public static void ExecuteSqlDataReader(string connectionString, string sqlCommand, Action readerCallBack) { RunWithOpenSqlConnection(connectionString, delegate(SqlConnection conn) { SqlCommand cmd = null; SqlDataReader reader = null; try { cmd = new SqlCommand(sqlCommand, conn); reader = cmd.ExecuteReader(); readerCallBack(reader); } catch (Exception ex) { //Log Error Here } finally { if (reader != null) reader.Dispose(); if (cmd != null) cmd.Dispose(); } }); } //Example calling these ExecuteSqlDataReader(ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString, "Select EmployeeID FROM Employees;", delegate(SqlDataReader reader) { List employeeIds = new List(); if (reader.HasRows) { while(reader.Read()) { employeeIds.Add((string)reader[0]); } } }); 

要回答您的具体问题,您可以为每个查询重用SqlConnection 。 只需确保在运行另一个查询之前关闭当前查询( SqlDataReader等),即。 用自己的块包装它们。

是的,您可以创建全局SqlConnection实例。 在我的例子中,我使用SqlConnection作为我通过Singleton访问的DataContext的成员。

 public class DatabaseDataContext : DataContext { private static DatabaseDataContext instance; private SqlConnection sqlConnection; private SqlTransaction sqlTransaction; //... public static DatabaseDataContext Instance { get { return instance ?? (instance = new DatabaseDataContext(connectionString)); } set { instance = value; } } } 

您可以通过关闭并打开此连接来封装您的事务,即:

 DatabaseDataContext.Instance.sqlConnection.Open(); // your transactions... sqlConnection.Close(); 

或者您可以将连接保持打开状态,而是专门开始和结束事务:

 DatabaseDataContext.Instance.sqlConnection.Open(); sqlTransaction = sqlConnection.BeginTransaction("Example Insert users"); try{ // ...your first transaction sqlTransaction.Commit(); } catch{sqlTransaction.Rollback();} sqlTransaction = sqlConnection.BeginTransaction("Update baked breads"); try{ // ...your second transaction sqlTransaction.Commit(); } catch{sqlTransaction.Rollback();} // Close the connection at some point sqlConnection.Close();