如何正确使用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);
如何正确使用SqlConnection相关推荐
- ADO.NET SQL
数据库应用程序开发基础篇-- .NET中SQL Server数据库的操作C#篇之一 写在前面:前面介绍了数据库系统的基本概念,SQl语句基本使用方法,接下来通过学习具体语言和具体数据库结合的应用开发来 ...
- 数据库应用程序开发基础篇—— .NET中SQL Server数据库的操作C#篇之一
数据库应用程序开发基础篇-- .NET中SQL Server数据库的操作C#篇之一 写在前面:前面介绍了数据库系统的基本概念,SQl语句基本使用方法,接下来通过学习具体语言和具体数据库结合的应用开发来 ...
- Unix编程/应用问答中文版(转)
Unix编程/应用问答中文版 名称 -- Unix编程/应用问答中文版 版本 -- 0.04 ( 2003-10-09 外发版 ) 维护 -- 小四 <scz@nsfocus.com> 主 ...
- GNU Make 使用手册(中译版)
如果要全面了解Linux的结构.理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级的Makefile文件.目前,在网上虽然有一些著作,但都不能全面的解释Linux源代码中各级的M ...
- 登录页面(通过数据库查询密码是否正确)
需求 通过在页面输入账号密码,实现从数据库查询数据并返回,验证成功后登录,打开主界面. 程序 using System; using System.Collections.Generic; using ...
- ADO.Net之SqlConnection、 Sqlcommand的应用(读书笔记1)
一.思维导图 1.关于SqlConnection类. 属性 ConnectionString 获取或设置用于打开 SQL Server 数据库的字符串. 方法 0pen() 使用 Connection ...
- SqlConnection调用Dispose方法之后还可以在连接池中复用吗?
在上一篇中简单讨论了SqlConnection的正确使用方式,顺带浅谈了一下连接池,不小心带出了一个问题:SqlConnection的Close和Dispose方法执行之后,该连接对象是不是真的放回到 ...
- 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确
记录一次很少见的Sql异常排查,异常内容: 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.参数 5 ("@TestValue"): 提供的值不是 ...
- python正确方法,方法 - 廖雪峰的官方网站
在一个对象中绑定函数,称为这个对象的方法. 在JavaScript中,对象的定义是这样的: var xiaoming = { name: '小明', birth: 1990 }; 但是,如果我们给xi ...
最新文章
- 编码最佳实践——Liskov替换原则
- Scikit-learn 数据预处理之归一化MinMaxScaler
- PHPExcel设置自动列宽
- openmp 互斥锁 mysql_openMP 函数总结(并行程序设计导论)
- 亚马逊ECS和Kubernetes管理百万容器8个洞察
- 基于主体掩码的实体关系抽取方法
- Spring框架----Confinguration和Component-Scan注解
- python安装Selenium,配置ChromeDriver
- Gatling性能测试(一)
- css关闭窗口按钮的代码,JS+CSS实现带关闭按钮DIV弹出窗口的方法
- 多位数据库专拣点评这本书
- 我的世界有宠物系统服务器,我的世界:如果Minecraft加入战斗宠物系统,推荐5大最强生物!...
- 九款即时通讯软件大盘点
- SAS9.4安装过程中的sid文件更新
- 发那科机器人xyz的方向_最全 | 发那科工业机器人示教器详细介绍
- 超能陆战队:迪士尼画风的漫威英雄
- 科技前沿一周必知:微软市值破万亿美元
- 2016阿里实习生面试经历
- java新浪微博客户端
- Flash中使用Filereference上传文件的一些注意事项