解析如何正确使用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.方法。结果如下:

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

(0)

相关推荐

  • 解析如何正确使用SqlConnection的实现方法

    以前曾见过有人这样写代码: 复制代码 代码如下: public class Service1 : IService1    {        private SqlConnection conn = new SqlConnection();        public void Method1()        {            //do something with conn;        }        public void Method2()        {        

  • Json_decode 解析json字符串为NULL的解决方法(必看)

    从APP端或从其他页面post,get过来的数据一般因为数组形式.因为数组形式不易传输,所以一般都会转json后再发送.本以为发送方json_encode(),接收方json_decode(),就解决的问题,结果发现,json_decode()后是NULL. 一般会反应是少了一个参数"true",但是回去看就是 json_decode($data,true); 那怎么还会是NULL呢?难道是编码,不会啊,接收后直接打印是一个完整json字符串的形式,在网上json解析网站,也是可以正常

  • php实现解析xml并生成sql语句的方法

    本文实例讲述了php实现解析xml并生成sql语句的方法.分享给大家供大家参考,具体如下: php解析xml有很多种办法,文档中有,搜索一下就一大把的. 今天遇到一个需求:将某个xml中的节点属性提取出来,然后更新数据库某一表中的字段. 思路: 解析XML,获取所有的节点属性 –> 循环节点集合,获取对应的属性 –> 拼接sql字符串存入一数组 –> 将数组转为字符串保存于某一文件中 这里使用了xpath,在写代码的过程中遇到两个问题: 1.xml的史路径属性为D:\xx\-时load不

  • jq源码解析之绑在$,jQuery上面的方法(实例讲解)

    1.当我们用$符号直接调用的方法.在jQuery内部是如何封装的呢?有没有好奇心? // jQuery.extend 的方法 是绑定在 $ 上面的. jQuery.extend( { //expando 用于决定当前页面的唯一性. /\D/ 非数字.其实就是去掉小数点. expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready wit

  • Jquery解析json字符串及json数组的方法

    本文实例讲述了Jquery解析json字符串及json数组的方法.分享给大家供大家参考.具体如下: <!doctype html> <html> <head> <meta charset="utf-8"> <script src="js/jquery-1.6.2.min.js"></script> </head> <body> <hr /> <h3>

  • PHP读取、解析eml文件及生成网页的方法示例

    本文实例讲述了PHP读取.解析eml文件及生成网页的方法.分享给大家供大家参考,具体如下: php读取eml实例,本实例可以将导出eml文件解析成正文,并且可以将附件保存到服务器.不多说直接贴代码了. <?php // Author: richard e42083458@163.com // gets parameters error_reporting(E_ALL ^ (E_WARNING|E_NOTICE)); header("Content-type: text/html; char

  • php解析字符串里所有URL地址的方法

    本文实例讲述了php解析字符串里所有URL地址的方法.分享给大家供大家参考.具体如下: <?php // $html = the html on the page // $current_url = the full url that the html came from //(only needed for $repath) // $repath = converts ../ and / and // urls to full valid urls function pageLinks($ht

  • 全面解析Windows下安装 mysql5.7的方法

    关于在windows下安装mysql 5.7 •要注意的新坑: 5.7版本安装后ROOT账号是有默认的密码的,这个密码在windows下可以在mysql.ini配置文件指定的data文件夹下面,那个为.err后缀名的文件里面找到. 2016-07-16T04:14:27.448186Z 1 [Note] A temporary password is generated for root@localhost: ?wxxx mysql的文件夹名字最好除掉,-, .这样的字符, 网上有其它安装帖子说

  • javascript将url解析为json格式的两种方法

    本文介绍了javascript将url解析为json格式的两种方法,分享给大家,具体如下: 方法一:最简单的方法,利用a标签来实现 function parseUrl(url){ var a=document.createElement('a'); a.href=url; return { protocol:a.protocol.replace(':',''), hostname:a.hostname, port:a.port, path:a.pathname, query:(()=>{ var

  • Android利用Gson解析嵌套多层的Json的简单方法

    首先先讲一个比较简单点的例子(最简单的我就不讲啦,网上很多),帮助新手理解Gson的使用方法: 比如我们要解析一个下面这种的Json: String json = {"a":"100", "b":[{"b1":"b_value1","b2":"b_value2"}, {"b1":"b_value1","b2"

随机推荐