发新话题
打印

菜鸟升级一号专题(已完成)

基于JDBC的数据库连接池高效管理策略

在基于JDBC的数据库应用开发中,数据库连接的管理是一个难点,因为它是决定该应用性能的一个重要因素。本文在对数据库连接进行透彻分析的基础上,提出并实现了一个高效的连接管理策略,使得开发高性能的数据库应用变得相对容易。特别是,对于连接管理中的两个难点:事务和多线程问题进行了深入的剖析,并给出了一个基于设计模式的解决方案。
介绍

在使用Java语言进行和数据库有关的的应用开发中,一般都使用JDBC来进行和数据库的交互,其中有一个关键的概念就是Connection(连接),它在Java中是一个类,代表了一个通道。通过它,使用数据的应用就可以从数据库访问数据了。

对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。

本文给出的方法可以有效的解决这个问题。在本方法中提出了一个合理、有效的连接管理策略,避免了对于连接的随意、无规则的使用。该策略的核心思想是:连接复用。通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。另外,由于对JDBC中的原始连接进行了封装,从而方便了数据库应用对于连接的使用(特别是对于事务处理),提高了开发效率,也正是因为这个封装层的存在,隔离了应用的本身的处理逻辑和具体数据库访问逻辑,使应用本身的复用成为可能。

问题产生\r

我参与的项目是开发一个网管系统,不可避免的要和数据库打交道。刚开始时,由于对于数据库的访问不是很频繁,对于数据库连接的使用就是简单的需要时就建立,用完就关闭的策略,这很符合XP(eXtreme Programming)的口号:"Do the Simplest Thing that Could Possibly Work"。确实,开始时工作的很好。随着项目的进展,对于数据库的访问开始变的频繁,问题就暴露出来了,原先的通过简单地获取和关闭数据库连接的方法将很大的影响系统的性能,这种影响是由于数据库资源管理器进程频繁的创建和摧毁那些连接对象而引起的。

此时,就有必要对数据库访问方法进行重构(refactoring),因为我们确实需要进行改进,来提高系统的性能。

解决方案

可以看出,问题的根源就是由于对于连接资源的低效管理造成的。对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁分配、释放所造成的问题的。把该模式应用到数据库连接管理领域,就是建立一个数据库连接池,提供一套高效的连接分配、使用策略,最终目标是实现连接的高效、安全的复用。

3.1、建立连接池

第一步,就是要建立一个静态的连接池,所谓静态是指,池中的连接是在系统初始化时就分配好的,并且不能够随意关闭的。Java中给我们提供很多容器类可以方便的用来构建连接池,如:Vector、Stack等。在系统初始化时,根据配置创建连接并放置在连接池中,以后所使用的连接都是从该连接池中获取的,这样就可以避免连接随意建立、关闭造成的开销(当然,我们没有办法避免Java的Garbage Collection带来的开销)。

3.2、分配、释放策略

有了这个连接池,下面我们就可以提供一套自定义的分配、释放策略。

当客户请求数据库连接时,首先看连接池中是否有空闲连接,这里的空闲是指,目前没有分配出去的连接。如果存在空闲连接则把连接分配给客户,并作相应处理,具体处理策略,在关键议题中会详述,主要的处理策略就是标记该连接为已分配。若连接池中没有空闲连接,就在已经分配出去的连接中,寻找一个合适的连接给客户(选择策略会在关键议题中详述),此时该连接在多个客户间复用。

当客户释放数据库连接时,可以根据该连接是否被复用,进行不同的处理。如果连接没有使用者,就放入到连接池中,而不是被关闭。

可以看出正是这套策略保证了数据库连接的有效复用。

3.3、配置策略

数据库连接池中到底要放置多少个连接,连接耗尽后该如何处理呢?这时一个配置策略。一般的配置策略是,开始时,根据具体的应用需求,给出一个初始的连接池中连接的数目以及一个连接池可以扩张到的最大连接数目。本方案就是按照这种策略实现的。

关键议题\r

本节将对上述解决方案中的关键细节进行详述,正是这些关键的策略保证了数据库连接复用的高效和安全。

4.1、引用记数

3.2节中的分配、释放策略对于有效复用连接非常重要,我们采用的方法也是采用了一个很有名的设计模式:Reference Counting(引用记数)。该模式在复用资源方面用的非常广泛,我们把该方法运用到对于连接的分配释放上。每一个数据库连接,保留一个引用记数,用来记录该连接的使用者的个数。具体的实现上,我们采用了两极连接池,空闲池和使用池。空闲池中存放目前还没有分配出去被使用的连接,一旦一个连接被分配出去,那么就会放入到使用池中,并且增加引用记数。

这样做有一个很大的好处,使得我们可以高效的使用连接,因为一旦空闲池中的连接被全部分配出去,我们就可以根据相应的策略从使用池中挑选出一个已经正在使用的连接用来复用,而不是随意拿出一个连接去复用。策略可以根据需要去选择,我们采用的策略比较简单:复用引用记数最小的连接。Java的面向对象特性,使得我们可以灵活的选择不同的策略(提供一个不同策略共用的抽象接口,各个具体的策略都实现这个接口,这样对于策略的处理逻辑就和策略的实现逻辑分离)。

4.2、事务处理\r

前面谈到的都是关于使用数据库连接进行普通的数据库访问。对于事务处理,情况就变得比较复杂。因为事务本身要求原子性的保证,此时就要求对于数据库的操作符合"All-All-Nothing"原则,即要么全部完成,要么什么都不做。如果简单的采用上述的连接复用的策略,就会发生问题,因为没有办法控制属于同一个事务的多个数据库操作方法的动作,可能这些数据库操作是在多个连接上进行的,并且这些连接可能被其他非事务方法复用。

Connection本身具有提供了对于事务的支持,可以通过设置Connection的AutoCommit属性为false,显式的调用commit或者rollback方法来实现。但是要安全、高效的进行Connection进行复用,就必须提供相应的事务支持机制。我们采用的方法是:采用显式的事务支撑方法,每一个事务独占一个连接。这种方法可以大大降低对于事务处理的复杂性(如果事务不独占一条连接,那么要保证事务的原子性并且又不妨碍复用该连接的其他和该事务无关的操作,基本上不可能,除非Connection类是你开发的),并且又不会妨碍连接的复用,因为隶属于该事务的所有数据库操作都是通过这一个连接完成的,并且事务方法又复用了其他一些数据库方法。

在我们的连接管理服务提供了显式的事务开始、结束(commit或者rollback)声明,以及一个事务注册表,用于登记事务发起者和事务使用的连接的对应关系,通过该表,使用事务的部分和我们的连接管理部分就隔离开,因为该表是在运行时根据实际的调用情况,动态生成的。事务使用的连接在该事务运行中不能被复用。

当使用者需要使用事务方法时,首先调用连接管理服务提供的beginTrans方法,该方法主要处理流程如下(伪码描述):

           public void beginTrans( ) {
                    …
                conn = getIdleConnectionFromPoll( );
                userId = getUserId( );
                registerTrans(userId, conn);
                    …
}






在我们的实现中,用户标识是通过使用者所在的线程来标识的。后面的所有对于数据库的访问都是通过查找该注册表,使用已经分配的连接来完成的。当事务结束时,从注册表中删除相应表项。

对于嵌套的事务如何处理呢?我们采用的方法仍为引用记数,不过这里的引用记数是指的"嵌套层次",具体的细节,不再赘述。

4.3、封装

从上面的论述可以看出,普通的数据库方法和事务方法对于连接的使用(分配、释放)是不同的,为了便于使用,对外提供一致的操作接口,我们对连接进行了封装:即普通连接和事务连接。在此,我们利用了Java中的强大的面向对象特性:多态。普通连接和事务连接均实现了一个DbConnection接口,对于接口中定义的方法,分别根据自己的特点作了不同的实现,这样在对于连接的处理上就非常的一致了。

4.4、并发问题\r

为了是我们的连接管理服务有更大的通用性,就必须要考虑到多线程环境,即并发问题。在一个多线程的环境下,我们必须要保证连接管理自身数据的一致性和连接内部数据是一致性,还好Java提供对这方面的很好的支持(synchronized关键字),这样我们就很容易使连接管理成为线程安全的。

5、结论

本文给出了一个基本的连接管理框架,在其中使用了一些广泛使用的设计模式(资源池,引用记数等),使得高效、安全的复用数据库连接成为可能。当然,还有一些问题没有考虑到,比如:没有实现对不同种类的数据库的联合管理;没有提供定时检测机制,查询连接的状态等。另外在连接管理的使用包装上比起一些商用的系统还显粗糙,但是底层的基理是一致的,所以通过本文相信对于这些商用的产品中的相关功能会有更好的理解。

参考文献
《Thinking in Java》Bruce Eckel

《Real-Time Design Patterns》 Bruce Powel Dougladd

TOP

加快WinXP窗口显示速度

我们可以通过修改注册表来改变窗口从任务栏弹出,以及最小化回归任务栏的动作,步骤如下:打开注册表编辑器,找到HKEY_ CURRENT_USER\Control Panel\Desktop\ WindowMetrics子键分支,在右边的窗口中找到MinAnimate键值,其类型为REG_SZ,默认情况下此健值的值为1,表示打开窗口显示的动画,把它改为0,则禁止动画的显示,接下来从开始菜单中选择“注销”命令,激活刚才所作的修改即可。

TOP

加快软驱传输速度

  可以通过修改系统注册表以获得较高的数据传输速度。具体方法如下:打开系统注册表编辑器,找到“HEKY_LOCAL_MACHINE\System\CurrentControlset\Services\Class\FCD\000”,在右边的窗口空白处,点击鼠标的右健新建一个“DWORD”值,命名为“Fore-Fifo”,健值设定为“0”。最后关闭注册表编辑器,重新启动电脑,一切就OK了

TOP

简单的网络入侵法

1.取得对方IP地址如XX.XX.XX.XX,方法太多不细讲了。


2.判断对方上网的地点,开个DOS窗口键入 TRACERT XX.XX.XX.XX


第4和第5行反映的信息既是对方的上网地点。


3.得到对方电脑的名称,开个DOS窗口键入 NBTSTAT -A XX.XX.XX.XX


第一行是对方电脑名称


第二行是对方电脑所在工作组


第三行是对方电脑的说明


4.在Windows目录下有一文件名为LMHOSTS.SAM,将其改名为LMHOSTS,删除其内容,将对方的IP及电脑名按以下格式写入文件:


XX.XX.XX.XX 电脑名


5.开DOS窗口键入 NBTSTAT -R


6.在开始-查找-电脑中输入对方电脑名,出现对方电脑点击即可进入。


以上方法请不要乱用,本人对你用上面的方法所惹出的麻烦概不负责,请慎重。


对付上面进攻的最好办法就是隐藏你的IP地址

TOP

A盘不见的解决方法

1、先检查硬件,连线是否正确、完好;

2、检查在BIOS中禁用了软盘驱动器,在“Standard CMOS Features”中,发现“Drive A”是否被设置成了“NONE”?

3、“开始”---“运行”---输入“gpedit.msc”运行组策略,在“用户配置---管理模板---Windows组件---资源管理器”右侧窗口中,找到“隐藏‘我的电脑’中这些指定的驱动器”,双击,
在属性框中检查是否将“未配置”设为“已启用”了;
在下拉菜单中是否选择了“仅限制驱动器A和B”;

TOP

解决窗口按钮上乱码问题

 问:我有一台电脑,操作系统是Win98第二版,现在不知是什么原因,窗口上的最小化、最大化和关闭按钮,还有菜单上的向下或向右的箭头全都成了乱码,我想问一下到底是哪个文件出了问题?

  答:在Win98中,Marlett是一个系统字体文件,窗口的最小化、最大化等按钮,就是用它来显示的。从你描述的情况可以看出,这个字体文件已经被破坏或被删除。你只要到安装了Win98第二版的机器上拷贝一个好的Marlett字体文件,然后再将它拷贝到自己系统的Windows\fonts目录下(都要在DOS状态下进行)就行了。如果本机上的Marlett.ttf文件存在但被破坏,那么先要去掉原来字体文件的隐藏属性,这样才能覆盖它。如果对DOS操作不熟悉,可以使用The Font Thing(下载地址:http://www.onlinedown.net/thefont.htm)之类软件在Windows下进行字体的拷贝和安装。

TOP

打开硬盘分区出错

  问:我用Windows优化大师对系统作了优化后,不知道是误操作还是怎么了,发现E盘图标变成优化大师图标,双击E盘会进入MS-DOS方式,单击右键然后选“打开”才能进入E盘,请问如何让E盘恢复正常?

  答:打开注册表编辑器,找到HKEY_CLASSES_ROOT\Drive,把右边的默认值里面的内容删除。图标的修改是:找到HKEY_CLASSES_ROOT\Drive\DefaultIcon,修改右边的图标为你需要的图标。以Windows XP为例,这个键值是:%SystemRoot%\System32\shell32.dll,8(不同的操作系统,该键值是不同的)。

TOP

解决控件提示问题

Q:我在用OE脱机浏览邮件时,总是出现这样的警告信息:“该页上的ActiveX控件不安全,当前安全设置禁止运行该页上的不安全控件,因此,可能无法正确显示该页”。“安全设置”中我设置的是“中”,即使调到低也是同样的情况,请问这是为什么,如何避免?

  A:这是因为OE(IE)中对Internet上Web页面的安全设置出现的一个提示信息。在“选项”的“安全设置”中,选定为“中”级时,“对没有标记为安全的ActiveX控件进行初始化和脚本运行”设为“禁用”;选定为“低”级时,则设为“提示”。这样,当浏览Web页面的邮件时,就会出现无法显示(“禁用”时)或不安全的提示(“提示”时)。如若我们确实需要浏览该Web页面的邮件时,可在OE(或IE)“选项”的“安全设置”中,选定为“自定义级别”,对“对没有标记为安全的ActiveX控件进行初始化和脚本运行”设为“启用”即可。为防不测,在浏览时要开启病毒监控。 (重庆 孙先华)

TOP

解决鼠标乱动问题

现象:鼠标有时胡乱乱动,不听指挥。我怀疑是有病毒或木马之类,所以用金山毒霸、iparmor5.33、the cleaner查杀过,均未发现过问题。但我在“系统信息→正在运行的任务”下发现几个没有路径、版本和任何信息的任务。不知道和这有没有关,请问这三个任务是什么东西,能否删除,怎样删除?

这是一种NIMDA病毒。解决方案如下:

(1) 检查临时文件夹是否存在MEPXXXX. tmp 和MEPXXXX.tmp.exe文件,XXXX是由字幕和数字随机组成的字符串。

(2) 检查C:\,D:\,E:\是否存在httpodbc.dll文件。

(3) 是否带宽被严重占用。

(4) 在Windows 9x/ME系统中,\Windows\ system目录下是否存在LOAD.exe文件。

(5) 在Windows NT/2K系统中,\Windows\ System目录下是否存在CSRSS.exe隐藏文件。

建议你下载Symantec和Trendmicro的查杀Nimda_E病毒工具进行检测和清除。http://support.marsec.net/focus/nimda_e/FxNimdaE.com

http://support.marsec.net/focus/nimda/trend_nimda.zip

查杀步骤:

(1)在http://support.marsec.net/focus/nimda_e/FxNimdaE.com下载FxNimdaE.com,存放在系统里。

(2)停掉系统所有正在运行的程序。如果你的系统是Windows Me,你必须停掉Windows Me的系统恢复功能,因为病毒有可能被自动保存在备份目录里。双击运行FxNimdaE. com,运行此程序需要你以系统管理员帐号登录,在操作前停掉IIS服务或者拔离网线,以免在清除过程中再次感染。然后点击Start键运行程序直到报告说系统已经清除掉病毒。

TOP

解决鼠标右键被锁定

  问:我的电脑不知道为什么鼠标右键被锁定了,用不了。请问如何解决?

  答:可能是有人在你的注册表中做了手脚,锁定了右键菜单。打开注册表编辑器,选择以下子键:

  “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer”在右窗格中找一个名为“NoViewContexMenu”的键值,把其数据改为00 00 00 00。或者干脆删除这个键值即可。

TOP

发新话题