如何正确使用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博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/10/31/2229738.html,如需转载请自行联系原作者

目录
相关文章
|
人工智能 机器人 测试技术
使用LM Studio在本地运行LLM完整教程
GPT-4被普遍认为是最好的生成式AI聊天机器人,但开源模型一直在变得越来越好,并且通过微调在某些特定领域是可以超过GPT4的。
6203 1
|
Docker 容器
OnlyOffice社区版破解最大连接限制部署
OnlyOffice社区版破解最大连接限制部署
|
Windows
Windows 10下安装Miniconda3
Windows 10下安装Miniconda3
2767 1
Windows 10下安装Miniconda3
|
API Windows
怎么申请 bing api key
1:打开网址 https://login.live.com/ 注册帐号并登录(点击上图中的登录按钮即可),在新窗口点击下方的“立即注册”(有帐号的可以直接登录)2:填写相关信息(推荐使用hotmail邮箱),填写完毕后点击下方的 即可PS:国家或地区请勿选择‘中国’,否则会出现‘在你的市场中未提供...
20048 1
|
Shell
Ubuntu20.04安装anaconda并默认激活conda base环境(步骤详细/操作简单实用)
Ubuntu20.04安装anaconda并默认激活conda base环境方法
20121 0
|
8月前
|
Linux Docker 容器
安装docker-18.06报错Error: libseccomp conflicts with docker-18.06
通过这些步骤,您可以成功在CentOS上安装Docker 18.06,并解决libseccomp的冲突问题。这些方法确保系统兼容性,并保证Docker的正常运行。
212 27
|
人工智能 Linux Docker
一文详解几种常见本地大模型个人知识库工具部署、微调及对比选型(1)
近年来,大模型在AI领域崭露头角,成为技术创新的重要驱动力。从AlphaGo的胜利到GPT系列的推出,大模型展现出了强大的语言生成、理解和多任务处理能力,预示着智能化转型的新阶段。然而,要将大模型的潜力转化为实际生产力,需要克服理论到实践的鸿沟,实现从实验室到现实世界的落地应用。阿里云去年在云栖大会上发布了一系列基于通义大模型的创新应用,标志着大模型技术开始走向大规模商业化和产业化。这些应用展示了大模型在交通、电力、金融、政务、教育等多个行业的广阔应用前景,并揭示了构建具有行业特色的“行业大模型”这一趋势,大模型知识库概念随之诞生。
154692 30
|
人工智能 API 异构计算
AI智能体研发之路-工程篇(四):大模型推理服务框架Xinference一键部署
AI智能体研发之路-工程篇(四):大模型推理服务框架Xinference一键部署
1320 2
|
人工智能 自然语言处理 搜索推荐
文本向量化模型新突破——acge_text_embedding勇夺C-MTEB榜首
在人工智能的浪潮中,大型语言模型(LLM)无疑是最引人注目的潮头。在支撑这些大型语言模型应用落地方面,文本向量化模型(Embedding Model)的重要性也不言而喻。 近期,我在浏览huggingface发现,国产自研文本向量化模型acge_text_embedding(以下简称“acge模型”)已经在业界权威的中文语义向量评测基准C-MTEB(Chinese Massive Text Embedding Benchmark)中获得了第一名。
文本向量化模型新突破——acge_text_embedding勇夺C-MTEB榜首
|
前端开发
CSS 鼠标样式和手指样式
巧合要用到鼠标样式效果,就顺便整理了下十五种CSS鼠标样式,小例子供大家使用啊。CSS鼠标样式语法如下: 任意标签中插入 style="cursor:*"   例 子:<span style="cursor:*">文本或其它页面元素</span>  <a href="#" style="cursor:*">文本或其它页面元素</a>
2042 0