• 如何正确使用SqlConnection


    以前曾见过有人这样写代码:

    public class Service1 : IService1
    
        {
    
            private SqlConnection conn = new SqlConnection();
    
            public void Method1()
    
            {
    
                //do something with conn;
    
            }
    
            public void Method2()
    
            {
    
                //do something with conn;
    
            }
    
            public void Method3()
    
            {
    
                //do something with conn;
    
            }
    
            public void Method4()
    
            {
    
                //do something with conn;
    
            }
    
        }
    

    在服务类中,新建一个全局的conn对象,然后使用conn对象来操作数据库。

    当然,还有一些不同的版本,比如:

    private SqlConnection conn = new SqlConnection();
    
    private static SqlConnection sconn = new SqlConnection();
    
    private SqlConnection Conn
    
    {
    
        get { return new SqlConnection(); }
    
    }
    

    如果有人问你哪种方式比较好,你会怎么回答?

    首先验证下在多线程环境下使用一个Connection的方式:

    创建控制台程序:

    Main代码如下:

    public static void Main()
    
    {
    
        string connectionString = @"Data Source=.\SQLEXPRESS;
    
                                    AttachDbFilename=""E:\DB\NORTHWND.mdf"";
    
                                    Integrated Security=True;
    
                                    Connect Timeout=30;User Instance=True";
    
        string connectionStringNoPooling = connectionString + " ;Pooling='false' ";
    
        SqlConnection conn = new SqlConnection(connectionString);
    
        new Thread(() => { ExecuteCommand(conn); }) { Name = "t1" }.Start();
    
        new Thread(() => { ExecuteCommand(conn); }) { Name = "t2" }.Start();
    
    }
    
    public static void ExecuteCommand(SqlConnection conn)
    
    {
    
        Console.WriteLine("Thread:{0},{1}", Thread.CurrentThread.Name, DateTime.Now);
    
        
    
        conn.Open();
    
        
    
        SqlCommand command = new SqlCommand("select * from customers", conn);
    
        command.ExecuteNonQuery();
    
        command.Dispose();
    
        Thread.Sleep(5000); //模拟耗时的查询
    
        conn.Close();
    
        Console.WriteLine("Thread:{0} 执行完毕,{1}", Thread.CurrentThread.Name, DateTime.Now);
    
    }
    

    代码很简单,模拟两个线程同时执行ExecuteCommand.方法。结果如下:

    image

    可以知道在多线程环境下使用一个Connection来执行Sql语句是不安全的,

    修改Main函数如下:将一个Connection,改为多个Connection

    public static void Main()
    
    {
    
        string connectionString = @"Data Source=.\SQLEXPRESS;
    
                                    AttachDbFilename=""E:\DB\NORTHWND.mdf"";
    
                                    Integrated Security=True;
    
                                    Connect Timeout=30;User Instance=True";
    
        string connectionStringNoPooling = connectionString + " ;Pooling='false' ";
    
        //SqlConnection conn = new SqlConnection(connectionString);
    
        //new Thread(() => { ExecuteCommand(conn); }) { Name = "t1" }.Start();
    
        //new Thread(() => { ExecuteCommand(conn); }) { Name = "t2" }.Start();
    
        SqlConnection conn1 = new SqlConnection(connectionString);
    
        SqlConnection conn2 = new SqlConnection(connectionString);
    
        new Thread(() => { ExecuteCommand(conn1); }) { Name = "t1" }.Start();
    
        new Thread(() => { ExecuteCommand(conn2); }) { Name = "t2" }.Start();
    
        Console.ReadLine();
    
    }

    运行结果如下:

    image

    既然多个Connection比一个Connection要好,

    为什么还是有人使用上面的那种写法来创建Connection呢?

    我认为他们可能会认为创建多个Connection比较耗时,而且多个Connection会占用内存,影响性能等等。。

    在这一点上可以使用测试数据来说明:

    测试数据来自:Connection-Pooling vs. Reusing one connection

    Run #

    NCP

    CP

    OC

    1

    4073

    374

    237

    2

    4032

    341

    298

    3

    3985

    353

    242

    4

    4085

    348

    269

    5

    3964

    369

    256

    6

    4203

    330

    207

    7

    4055

    341

    359

    8

    4071

    357

    286

    9

    3968

    363

    356

    10

    4023

    349

    359

    AVG

    4046

    353

    287

    Run #:1代表1000次查询,2代表2000次查询

    NCP :Not Connection Pool ,未启用数据库连接池

    CP :Connection Pool,启用数据库连接池

    OC :One Connection,一个连接对象

    从图表可以发现启用了连接池的方式并不比重用一个连接慢多少。

    但是从稳定性,程序的健壮性来说,CP的方式明显的好于OC。

    所以下次实现服务,或者是查询的时候完全可以使用

    public SqlConnection Connection
    
    {
    
        get
    
        {
    
            return new SqlConnection(@"...");
    
        }
    
    }

    而不要

    private SqlConnection conn = new SqlConnection(connectionString);

    作者:LoveJenny
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Django之admin
    CSS弹性盒子
    SQL SERVER按多字段查找重复的数据并删除只保留一条
    计算机名称改名之后,tfs连接问题
    Docker镜像仓库Harbor部署
    搭建docker本地仓库
    部署docker swarm集群
    Dockerfile
    centos 7 安装docker 常用指令
    python软件安装-Windows
  • 原文地址:https://www.cnblogs.com/LoveJenny/p/2229738.html
Copyright © 2020-2023  润新知