Web应用程序的多线程DBhelper

烟波钓 2011-11-24 04:19:34
鄙人一直有疑问:
1. Web应用程序中的Dbhelper中的方法一般为静态的,原因貌似静态的方法在程序一次加载时就实例化好了,此处采用静态方法的好处是:由于程序跟库进行操作是一个“频繁的”“一直存在”的事情,所以这块采用静态的方法,不知小生理解是否正确
2.Web程序是面向多客户端的,那么多个客户端访问数据都是通过这几个静态方法(变态一点的还是同一个连接对象),那这之间为何没有产生冲突?
例子:A客户端的一个跟库操作的方法刚好走到 连接对象的Close()方法的前一句。
B客户端的一个跟库操作的方法走到 连接对象的Open()方法
下一个时段 A的方法中走完了close(),那么此时连接对象应该是关闭状态,此时B的方法走到ExecuteScalar()以及类似的方法,但我并没有发现此时会报错。
求大侠解释一下我的这个疑问

另:我现在在一个网页的响应方法中开了多个线程,并且都是异步的,此时不对Dbhelper中的方法加锁机制的话会不会出问题?我试验的貌似出问题了……
若是需要加锁,不想一味的直接加锁,这样会对性能造成影响,求一套比较好的加锁机制


分不够可以在家 大侠们给力!!!!
...全文
317 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhengsb 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 yanbuodiao 的回复:]
引用 33 楼 zhengsb 的回复:
25楼没有使用源码格式,比较乱,重贴一下:

C# code
public class DbHelper
{
#region 私有构造和私有变量
/// <summary>
/// 私有构造函数
/// </summary>
private DbHelper()
{
……

3q 能给一些关于这些东西的介绍么 关于性能啥的
[/Quote]
了解一些有关设计模式方面的东西或许对你有帮助
全局变量 2011-11-28
  • 打赏
  • 举报
回复

using (SqlConnection connection = new SqlConnection(connectionString))
{
} 大家应该都是在调用时重新NEW
zincy 2011-11-28
  • 打赏
  • 举报
回复
用微软企业库处理数据库操作
烟波钓 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 zhengsb 的回复:]
25楼没有使用源码格式,比较乱,重贴一下:

C# code
public class DbHelper
{
#region 私有构造和私有变量
/// <summary>
/// 私有构造函数
/// </summary>
private DbHelper()
{
……
[/Quote]
3q 能给一些关于这些东西的介绍么 关于性能啥的
烟波钓 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 zhengsb 的回复:]
引用 40 楼 yanbuodiao 的回复:
引用 39 楼 zhengsb 的回复:
"这个就是看完单例模式的时候搞了,",你这个貌似不是单例模式吧?
嘿嘿 当然不是 现在在一个小网站上做做实验 只是想先搞清楚这样做好不好 现在我得到的信息就是连接对象不能是静态的字段了 那这个Dbhelper搞成单例模式的在这种需求下可以不?

当然可以
[/Quote]3Q 这个帖子结了 觉得有必要好好讨论一下静态变量 静态类 静态方法 这三者的应用范围、优缺点及可能产生的问题
zhengsb 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 yanbuodiao 的回复:]
引用 39 楼 zhengsb 的回复:
"这个就是看完单例模式的时候搞了,",你这个貌似不是单例模式吧?
嘿嘿 当然不是 现在在一个小网站上做做实验 只是想先搞清楚这样做好不好 现在我得到的信息就是连接对象不能是静态的字段了 那这个Dbhelper搞成单例模式的在这种需求下可以不?
[/Quote]
当然可以
烟波钓 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 zhengsb 的回复:]
"这个就是看完单例模式的时候搞了,",你这个貌似不是单例模式吧?
[/Quote]嘿嘿 当然不是 现在在一个小网站上做做实验 只是想先搞清楚这样做好不好 现在我得到的信息就是连接对象不能是静态的字段了 那这个Dbhelper搞成单例模式的在这种需求下可以不?
zhengsb 2011-11-28
  • 打赏
  • 举报
回复
"这个就是看完单例模式的时候搞了,",你这个貌似不是单例模式吧?
烟波钓 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 zhengsb 的回复:]
引用 34 楼 yanbuodiao 的回复:
引用 33 楼 zhengsb 的回复:
25楼没有使用源码格式,比较乱,重贴一下:

C# code
public class DbHelper
{
#region 私有构造和私有变量
/// <summary>
/// 私有构造函数
/// </summary>
private DbHelper()
{
……

3q……
[/Quote]

这个就是看完单例模式的时候搞了,在前公司的C/S架构的我自己编写的类似这样的DBhelper性能上也还是比直接搞下来的东西要好些 当然了 那个系统都是通过每个客户端自己的程序去访问服务器的数据库的

现在准备来一套适用于这种B/S架构的东西,当然了还可能加入一些其他可变性,例如一个系统内支持不同的库,不同连接字串等等,还得考虑到上层调用这个Dbhelper时的易用性等等

呵呵,所以现在很有必要好好了解这些
烟波钓 2011-11-26
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zhengsb 的回复:]
楼主在主贴中的第2点,没发现不等于不存在,应该只是没达到临界点,调试状态不同于运行状态.
从代码的执行流程上来看,必定会产生冲突的.
[/Quote] 呵呵 谢谢啊 也就是说 这个链接对象是不能这样搞的 应该搞成 直接实例化对象的是吧


现在真有点乱了 找了很多资料 有关于这个DBHepler里面方法之静态还是动态的争论

大牛们给教育一下啊
烟波钓 2011-11-26
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 sp1234 的回复:]
引用 12 楼 yanbuodiao 的回复:
private static readonly SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ToString());

这种static的东西,你试试看,当一个请求正在使用它(例如DbDataReader正在……
[/Quote]

我以前做C/s项目的时候有用过类似的东西(不涉及网络通信的) 全装的客户端的那种


现在意识到这个东西在B/S,及多线程下会出问题 所以上来问问 呵呵 有啥推荐的帖子给看看啥的 谢谢啊
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yanbuodiao 的回复:]
private static readonly SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ToString());
[/Quote]
这种static的东西,你试试看,当一个请求正在使用它(例如DbDataReader正在读)的时候,别的请求是不都就垮掉了?!

看来你没有遇到过实际的项目。
zhengsb 2011-11-26
  • 打赏
  • 举报
回复
楼主在主贴中的第2点,没发现不等于不存在,应该只是没达到临界点,调试状态不同于运行状态.
从代码的执行流程上来看,必定会产生冲突的.
zhengsb 2011-11-26
  • 打赏
  • 举报
回复
public class DbHelper
{
#region 私有构造和私有变量
/// <summary>
/// 私有构造函数
/// </summary>
private DbHelper()
{
}
/// <summary>
/// 获取一个数据库连接对象
/// </summary>
private static SqlConnection GetConn()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ToString());
con.Open():
return con;
}
#endregion

#region 返回受影响的行数
/// <summary>
/// 按照指定的语句对数据表进行操作,返回受影响的行数
/// </summary>
/// <param name="sqlStr">操作语句</param>
/// <returns>受影响的行数</returns>
public static int ExecuteNonQuery(string sqlStr)
{
int mark = 0;
SqlConnection con=null;
try
{
con=GetConn();
SqlCommand cmd = new SqlCommand(sqlStr, con);
mark = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
PubFunction.ErrorLogPrint(sqlStr, ex.ToString());
}
finally
{
if (con!=null)
{
con.Close();
con.Dispose();
}
}
return mark;
}
}

zhengsb 2011-11-26
  • 打赏
  • 举报
回复
楼主12楼贴的代码中,conn是共享的,这种方式非常容易引发冲突,即使你使用了锁机制把这种冲突消除了,但由此将带来另一个问题:所有操作变成串行化操作,这样将严重降低应用的性能及效率.
烟波钓 2011-11-26
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 charles_y 的回复:]
连接池跟这个是两个概念,连接池是Ado.net的系统机制,为了防止建立连接费时费力,节省时间。

连接池的机制是这样的:只要连接池还有空间,就把程序用完了需要销毁的连接放入连接池。一旦有程序要求建立连接,就从连接池中取一个给它,而不是真的创建一个新的连接。
[/Quote]

ok 这个以前看过 这次再看 一下懂了 那就回归到这个问题上来:
静态方法的并发执行是如何执行的?

个人一直理解为静态方法在内存中仅有一份 大家都过来用不会产生冲突 必然有神马机制 求解释
charles_y 2011-11-26
  • 打赏
  • 举报
回复
连接池跟这个是两个概念,连接池是Ado.net的系统机制,为了防止建立连接费时费力,节省时间。

连接池的机制是这样的:只要连接池还有空间,就把程序用完了需要销毁的连接放入连接池。一旦有程序要求建立连接,就从连接池中取一个给它,而不是真的创建一个新的连接。
zhengsb 2011-11-26
  • 打赏
  • 举报
回复
25楼没有使用源码格式,比较乱,重贴一下:
	public class DbHelper
{
#region 私有构造和私有变量
/// <summary>
/// 私有构造函数
/// </summary>
private DbHelper()
{
}
/// <summary>
/// 获取一个数据库连接对象
/// </summary>
private static SqlConnection GetConn()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ToString());
con.Open():
return con;
}
#endregion

#region 返回受影响的行数
/// <summary>
/// 按照指定的语句对数据表进行操作,返回受影响的行数
/// </summary>
/// <param name="sqlStr">操作语句</param>
/// <returns>受影响的行数</returns>
public static int ExecuteNonQuery(string sqlStr)
{
int mark = 0;
SqlConnection con=null;
try
{
con=GetConn();
SqlCommand cmd = new SqlCommand(sqlStr, con);
mark = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
PubFunction.ErrorLogPrint(sqlStr, ex.ToString());
}
finally
{
if (con!=null)
{
con.Close();
con.Dispose();
}
}
return mark;
}
}
}
zhengsb 2011-11-26
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 yanbuodiao 的回复:]
引用 26 楼 zhengsb 的回复:
楼主在主贴中的第2点,没发现不等于不存在,应该只是没达到临界点,调试状态不同于运行状态.
从代码的执行流程上来看,必定会产生冲突的.
呵呵 谢谢啊 也就是说 这个链接对象是不能这样搞的 应该搞成 直接实例化对象的是吧


现在真有点乱了 找了很多资料 有关于这个DBHepler里面方法之静态还是动态的争论

大牛们给教育一下啊
[/Quote]
静态变量是全局共享的,如果你的程序中确保方法不存在重入则不会发生问题,但是如果你的程序不能做到无重入的话则不应该使用静态变量.
  • 打赏
  • 举报
回复
[Quote=引用楼主 yanbuodiao 的回复:]
鄙人一直有疑问:
1. Web应用程序中的Dbhelper中的方法一般为静态的,原因貌似静态的方法在程序一次加载时就实例化好了,此处采用静态方法的好处是:由于程序跟库进行操作是一个“频繁的”“一直存在”的事情,所以这块采用静态的方……
[/Quote]

首先要注意,别把静态方法跟静态变量混为一谈。
加载更多回复(18)

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧