单例模式在数据库连接的中的应用

glchengang 2004-01-13 11:05:31
有一朋友的项目在数据库连接上应用了单例模式,项目环境是oracle、weblogic、jsp,他们将数据库的连接对象做成了单例模式。这样做的人估计不在少数,请大家参与讨论,这样设计的好坏。



我的观点:此设计是大大的错误,会导致严重的性能问题。理由是:如果数据库连接做成单例模式也就是说系统只会存在一个数据库连接实例,大家公用。但这一实例可以并发使用吗?我认为不能,因此存在排队。另外一个数据库连接实例对应于weblogic连接池的一个数据库连接,如果做成了单例,那么weblogic连接池的连接的使用数不会超过一个,那么weblogic连接池没有任何意义。由此在这里又生出以下问题:

1、单例模式中共用的单一实例可以并发使用吗?不用单例模式是否执行速度会更快些,因为在使用实例时不用排队争用,而是各有一个实例可用(当然多个实例内存占用会多,另外创建实例也会花一些时间)。

2、一个数据库连接对象实例是否只对应于weblogic连接池的一个数据连接?


<<java与模式>>一书中有关于单例模式在数据库连接的应用的内容(216页.例子二),作者不赞成将单例模式用于数据库链接,但原因说得很弱,只是说“connection对象可以同时有几个实例共存,不必是单一实例。”,但如果我的观点是正确的,或者大体正确的,那么“不必是”就应改“不应是,不能是”,因为它会使系统运行效率大打折扣,特别是那么高访问量的网站将更明显(我的朋友项目是某通讯运营商的查话费系统)。

...全文
1947 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
glchengang 2004-01-15
  • 打赏
  • 举报
回复
正好我下一个的项目就是用java来写application是client/server的。您的建议我正好用上。
glchengang 2004-01-13
  • 打赏
  • 举报
回复
jeffyan77(jeffyan77) : 谢谢您的回答。
  您的第二段对我很有启发,正如您所说系统的排队是不可避免的,但尽量将排队的工作交给更低一层来做,这样可以获得更高的效率。cpu-->操作系统-->数据库,jvm-->应用系统。
  还有我没有注意到:<<java与模式>>不仅仅是面向j2ee读者。您所说”只有一个用户在使用,唯一的问题就是系统可能需要几个connection,譬如两个、三个等,而不是而不是一个“,我的理解是单用户界面也可能会需要两个以上的数据连接,比如他同时开两个以上窗口做不同的数据库操作。
  多例模式我今天正在读,再次感谢您的回答和您写的书。我想这一个帖子应该对学习单例模式的人应该有所帮助。
jeffyan77 2004-01-13
  • 打赏
  • 举报
回复
你对问题考虑得很仔细,这很好。但是你的问题与我的书中的问题不同,我在书中举的例子并不是J2EE项目中的例子,而是一般的项目,包括单用户系统。你考虑问题的角度与我书中考虑问题的角度也不相同,从设计模式的角度上讲,无法导出“严重的错误来”,在实际系统中也不一定是严重的错误,要看是什么情况。

我们从资源角度讲吧。资源有两种,一种需要排队,一种不需要排队,或者需要一种复杂的排队,譬如数据库就是复杂的排队问题,应该由数据库引擎自行解决,解决方式就是纪录的locking,而locking不应该由Java程序解决。

我昨天讲过,单例模式管理是需要排队的,因为你在上一个问题里面考虑的是配置文件的写操作问题,单例模式如何应用到这种情况,基本上就是《Java与模式》一书中讲得那样,这已经没有问题了吧。

关于把单例模式应用到数据库connection的问题较为复杂,如果是简单地把一个connection对象封存在单例对象中,那么在J2EE环境中这是错误的,你说得是对的;但是在单用户系统中这并不是什么严重的问题,因为在某一个时刻只有一个用户在使用,唯一的问题就是系统可能需要几个connection,譬如两个、三个等,而不是一个(不知道为什么的话我下次解释)。注意在我的书中并没有说明是什么样的系统,在你的问题里你限定为J2EE多用户系统,这是很不一样的。

那么单例模式是不是就不能应用到J2EE服务器系统中了哪?也不是,单例模式可以用来管理一个connection pool。现在恐怕没有人会自己写一个connection pool,但在三四年前并没有商业化的connection pool, 全靠自己写。单例模式可以用来保存这样一个connection pool,在初始化的时候创建譬如100个connection对象,然后再需要的时候提供一个,用过之后返回到pool中。如果不是用单例模式的话,这个pool存在哪里,就是一个问题。最后可能只好存到Application对象中。

呵呵,问题并不是你想得那么简单。建议你再读一读后面的几章,特别是多例模式的那两章。

对于你朋友的情况来说,根本就不需要使用单例模式。他需要一个工厂模式,把创建connection对象的逻辑包装到工厂对象中就可以了。总的来说,我劝读者尽可能少用单例模式,因为我发现了大量例子,都是单例模式被错误地使用的情况。
jeffyan77 2004-01-13
  • 打赏
  • 举报
回复
现在的朋友可能没有太多经验写单用户程序,所谓单用户就是指client/server程序,在client一端只有一个用户,在数据库端有多个用户。

在客户端常常需要把例外记录到数据库中,这需要一个connection。此外,常常需要一个connection读取数据,另一个connection进行一个transaction。有一些很罕见的可能性,就是需要两个独立的transaction。我的经验,一个单用户程序至少需要两到三个connection。

50,547

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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