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

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.方法。结果如下:

可以知道在多线程环境下使用一个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();
}

运行结果如下:

既然多个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);

如何正确使用SqlConnection相关推荐

  1. ADO.NET SQL

    数据库应用程序开发基础篇-- .NET中SQL Server数据库的操作C#篇之一 写在前面:前面介绍了数据库系统的基本概念,SQl语句基本使用方法,接下来通过学习具体语言和具体数据库结合的应用开发来 ...

  2. 数据库应用程序开发基础篇—— .NET中SQL Server数据库的操作C#篇之一

    数据库应用程序开发基础篇-- .NET中SQL Server数据库的操作C#篇之一 写在前面:前面介绍了数据库系统的基本概念,SQl语句基本使用方法,接下来通过学习具体语言和具体数据库结合的应用开发来 ...

  3. Unix编程/应用问答中文版(转)

    Unix编程/应用问答中文版 名称 -- Unix编程/应用问答中文版 版本 -- 0.04 ( 2003-10-09 外发版 ) 维护 -- 小四 <scz@nsfocus.com> 主 ...

  4. GNU Make 使用手册(中译版)

    如果要全面了解Linux的结构.理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级的Makefile文件.目前,在网上虽然有一些著作,但都不能全面的解释Linux源代码中各级的M ...

  5. 登录页面(通过数据库查询密码是否正确)

    需求 通过在页面输入账号密码,实现从数据库查询数据并返回,验证成功后登录,打开主界面. 程序 using System; using System.Collections.Generic; using ...

  6. ADO.Net之SqlConnection、 Sqlcommand的应用(读书笔记1)

    一.思维导图 1.关于SqlConnection类. 属性 ConnectionString 获取或设置用于打开 SQL Server 数据库的字符串. 方法 0pen() 使用 Connection ...

  7. SqlConnection调用Dispose方法之后还可以在连接池中复用吗?

    在上一篇中简单讨论了SqlConnection的正确使用方式,顺带浅谈了一下连接池,不小心带出了一个问题:SqlConnection的Close和Dispose方法执行之后,该连接对象是不是真的放回到 ...

  8. 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确

    记录一次很少见的Sql异常排查,异常内容:         传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.参数 5 ("@TestValue"): 提供的值不是 ...

  9. python正确方法,方法 - 廖雪峰的官方网站

    在一个对象中绑定函数,称为这个对象的方法. 在JavaScript中,对象的定义是这样的: var xiaoming = { name: '小明', birth: 1990 }; 但是,如果我们给xi ...

最新文章

  1. 编码最佳实践——Liskov替换原则
  2. Scikit-learn 数据预处理之归一化MinMaxScaler
  3. PHPExcel设置自动列宽
  4. openmp 互斥锁 mysql_openMP 函数总结(并行程序设计导论)
  5. 亚马逊ECS和Kubernetes管理百万容器8个洞察
  6. 基于主体掩码的实体关系抽取方法
  7. Spring框架----Confinguration和Component-Scan注解
  8. python安装Selenium,配置ChromeDriver
  9. Gatling性能测试(一)
  10. css关闭窗口按钮的代码,JS+CSS实现带关闭按钮DIV弹出窗口的方法
  11. 多位数据库专拣点评这本书
  12. 我的世界有宠物系统服务器,我的世界:如果Minecraft加入战斗宠物系统,推荐5大最强生物!...
  13. 九款即时通讯软件大盘点
  14. SAS9.4安装过程中的sid文件更新
  15. 发那科机器人xyz的方向_最全 | 发那科工业机器人示教器详细介绍
  16. 超能陆战队:迪士尼画风的漫威英雄
  17. 科技前沿一周必知:微软市值破万亿美元
  18. 2016阿里实习生面试经历
  19. java新浪微博客户端
  20. Flash中使用Filereference上传文件的一些注意事项

热门文章

  1. mybatis中的TypeAliasRegistry
  2. mybatis中缓存的设计与原理
  3. Qt实现应用程序单实例运行--LocalServer方式
  4. Bootstrap相关优质项目学习清单
  5. 20155303 2016-2017-2 《Java程序设计》第六周学习总结
  6. 改进筛法- 质数中的质数(质数筛法)
  7. Caffe源码解析5:Conv_Layer
  8. win7启动后报丢失nscmk.dll解决解决方式
  9. BZOJ2819 Nim
  10. == Equals ReferenceEquals 的区别