品管工具QC七大手法BSSQC数据库连接和事务管理专题.docx
- 文档编号:29311662
- 上传时间:2023-07-22
- 格式:DOCX
- 页数:8
- 大小:39.47KB
品管工具QC七大手法BSSQC数据库连接和事务管理专题.docx
《品管工具QC七大手法BSSQC数据库连接和事务管理专题.docx》由会员分享,可在线阅读,更多相关《品管工具QC七大手法BSSQC数据库连接和事务管理专题.docx(8页珍藏版)》请在冰豆网上搜索。
品管工具QC七大手法BSSQC数据库连接和事务管理专题
(品管工具QC七大手法)BSS_QC_数据库连接和事务管理专题
BSS系统中数据库连接的安全使用和事务问题汇总
V1.0.1
修改日期
原因
修改人
2007-09-30
根据zhaoxin的意见,修改了Hibernate的session连接管理
刘世伟
2007-11-8
根据调优组当前的工作,补充了壹些内容
刘世伟
几个名词解释:
1、数据库连接池:
众所周知,建立数据库连接是壹个昂贵的操作,每次均得花费约0.05s~1s的时间,消耗壹定的内存资源(Oracle9i的壹个空闲连接约需2~5MB内存,非空闲连接约需几十MB左右内存),而且壹旦到达临界点,系统会陷入资源管理的恶性循环:
越来越慢。
数据库连接池的基本思想就是为数据库连接建立壹个“缓冲池”。
预先于缓冲池中放入壹定数量的连接备用,减少使用时才创建、销毁的消耗。
当需要建立数据库连接时,只需从“缓冲池”中取出壹个,使用完毕之后再放回去。
使用连接池后,数据库服务器减少了它且不擅长的连接管理工作,通过池连接的快速复用,能够为客户端提供更大的且发量,内存消耗也于可控范围内波动。
我们能够通过设定连接池最大连接数来防止系统无尽的和数据库连接,控制数据库的压力。
我们也能够通过连接池的管理机制监控数据库连接的数量﹑使用情况,为系统开发﹑测试及性能调优提供依据。
2、真实连接:
客户端程序直接和数据库建立的Connection,使用完毕需要及时、安全的关闭,否则会导致数据库内存资源泄漏、服务器宕机
3、代理连接:
客户端程序从连接池获取的Connection,它实际上是封装了真实连接,提供和真实连接相同的功能,使用完毕也需要及时、安全的关闭,否则连接池中的连接得不到释放,会导致连接池中可用的空闲连接越来越少。
当然,由于存于连接池的控制,数据库不会因此而宕机。
壹、BSS数据库连接管理现状:
BSS系统中对数据库连接的管理,是统壹通过数据源(DataSource)管理的,存于连接池和单连接俩种方式的数据源(详情参考modelxxx.jar中的xxxDatabase.xml文件)
1、连接池数据源,命名方式为“xxxDataSource”,BSS采用了apache的开源池mons.dbcp.BasicDataSource,应用程序获取的是apache连接池的代理连接(connectionProxy),非真实连接。
2、单连接数据源,命名方式为“xxxDataSourceNoPool”,BSS采用了Spring框架的org.springframework.jdbc.datasource.DriverManagerDataSource,程序获取的是真实的数据库连接。
二、BSS系统中对数据源的使用
1、Hibernate的SessionFactory,使用的是连接池数据源,于配置文件中壹般命名为“xxxSessionFactory”,而且Hibernate本身包含壹个简单的连接池hibernate.connection,但性能和功能不如apache的。
2、Spring的JdbcTemplate,根据其使用数据源是否为连接池,命名方式也不同,配置文件中对使用连接池数据源的命名为“xxxJDBC”,使用单连接数据源的命名为“xxxJDBCNoPool”
三、应用程序中对连接的使用
BSS程序中使用Hibernate的session和JdbcTemplate提供的通用方法壹般是够用的,但某些场景下如执行oracle特性的SQL语句或存储过程,需要获取真实数据库连接,当下主要使用以下几种方式:
1、Hibernate中,通过getSession().connection(),此时获取的是连接是根据其数据源决定的,如果通过连接池中获取,则是代理连接,否则是真实数据库连接,但注意,无论如何均不能用conn.close()语句显示关闭的;这时候的conn其实是被session管理了,Hibernate会于Session的事务提交或回滚的时候,自动把连接放回池中,如果我们主动关了,会抛异常。
2、JdbcTemplate中,通过jdbc.getDataSource().getConnection(),此时获取的连接是根据其数据源决定的,如果jdbc.getDataSource()返回的是连接池数据源,则连接是连接池的连接代理(重载了真实连接的close方法),需要从代理连接中再次获取真实连接,见下面的a段落;如果返回的是单连接的数据源,则返回的是真实连接。
这2种连接均需要显式的close关闭,前者表示把连接仍回连接池继续使用,后者表示真正关闭连接,释放数据库内存。
a)对JdbcTemplate中返回代理连接的情况,由于是连接代理,对Oracle的Blob和Clob大数据对象,于CLOB.createTemporary(conn,true,CLOB.DURATION_SESSION)的时候,会抛ClassCastException,此时需要获取真实的物理连接,方法如下:
i.设置DataSource中连接池的accessToUnderlyingConnectionAllowed属性的值为true,表示允许从连接代理中获取物理连接;
ii.对apache的BasicDataSource,可通过mons.dbcp.DelegatingConnection的getDelegate()方法获取真实连接。
iii.注意,通过连接池代理连接而获取的真实连接壹定不能直接关闭,否则连接池就没有意义了,最好把这种情况下的获取物理连接+创建Clob用方法屏蔽掉,防止被误关闭。
代码扫描后发现系统中普遍存于的问题:
1、对打开的数据库资源conn、ps、rs,主动写了close语句,可是没有写于finally语句块里面,壹旦发生异常,那么close语句就会被旁路,导致资源得不到释放。
2、没有主动写close语句,当然这个是存于壹些争议的,请见以下解释:
a、如果不使用连接池机制,关闭connection,会自动关闭resultset和statement的,程序中能够不显示关闭;
b、如果使用连接池,所谓的关闭connection,其实是将连接返回给了连接池,连接对象依然存于,实际上不是物理关闭,因此,必须显示的关闭resultset和statement,否则连接池中连接上的rs和ps会越来越多。
3、单独写了close的语句块,到没什么问题,见着不舒服罢了。
附件是代码中问题的位置,请详见。
建议:
我们系统有使用连接池和单独创建连接的,所以保险起见,resultset和statment(PreparedStatement、CallableStatement)壹定于finally语句里面主动保持先后次序close掉,于此贴壹下示例程序。
------------------------------
Connectioncon=null;
PreparedStatementps=null;
ResultSetrs=null;
try{
.....
}
catch(SQLExceptionex){
....
}
finally{
try{
if(rs!
=null)
rs.close();
}
catch(SQLExceptionex){
///错误处理
}
try{
if(ps!
=null)
ps.close();
}
catch(SQLExceptionex){
///错误处理
}
try{
if(con!
=null)//注意:
Hibernate中得到的conn不能关闭。
con.close();
}
catch(SQLExceptionex){
///错误处理
}
}
数据库事务管理现状:
BSS中采用了Spring的声明式事务管理,于配置文件中通过对象或方法的名称通配事务的加载和否。
由于存于之上的数据库连接管理方式,所以对数据库的事务管理也是存于多种方式:
1、Hibernate的session
2、JdbcTemplate
3、通过session或jdbcTemplate获取的Connection,壹般直接执行sql语句和存储过程
存于的问题:
1、事务回滚规则只有DAOException(部分),缺BssException
当下BMO中规范抛出BssException,壹旦BMO方法中出现异常,当下的配置是事务不回滚的,导致前后数据不完整。
建议,spring事务配置里面加入强制回滚模式匹配:
-mon.BssException,如下:
EJB事务回滚规则:
1、如果bean抛出RuntimeException,容器会自动回滚事务,且且于外面包装壹个RemoteException抛出。
2、如果bean抛出其他的异常,容器不会做任何处理,除非强制定义。
2、事务拦截粒度比较粗,定义于类级别而不是方法级别
事务拦截器的配置于bean的名称上,该bean下所有的方法均按照同壹种事务模式
象readonly的事务隔离模式,对只查询不修改的方法,性能提高比较大,但需要更改拦截器,定义于方法级别。
此条只涉及性能,影响不是很大,可酌情。
3、EJB和spring的事务传递问题
如果BMO中spring不加载事务,被EJB包装后,发现EJB的事务不能传递给spring,EJB事务回滚了,可是spring管理bean的事务仍旧提交了,原因待详查,初步分析是ejb容器和spring容器事务不能透传,按照EJB规范,CMT(容器管理的事务)内部是不能有嵌套事务的。
当前为规避此种情况,建议所有的BMO,如果需要事务的,名称壹律按照规范以“Manager”“DAO”结尾。
『调优组正于组织力量集中解决这个问题,初步思路是启用EJBBMT(Bean管理事务),使用websphere的事务管理和连接池』
存储过程和Java事务的嵌套问题:
于壹个bmo中同时调用几个dao,dao中分别用hibernate、jdbc和存储过程完成insert或update操作,事务是能够完整的,不过需要注意2点:
壹是存储过程里面不能有commit和rollback
二是dao调用存储过程后,dao中也不要写commit和rollback,只要close就能够,由事务控制自动提交,除非捕捉到bssexception,这里要于spring的事务拦截中配壹下bssexception、daoException,这样就能够控制异常的回滚。
遗留问题:
1、采用连接池后,如果数据库存储过程重新编译后,连接池连接的过程会存于问题。
这个问题和连接池的statement缓存有关系,如果关闭语句缓存,应该能解决这个问题,可是要评估性能的影响。
答:
已经做过试验,没有影响,第壹次调用抛失效异常,第二次就会刷新状态。
但需要注意的是,存储过程的于线编译,往往会带来大量的锁,导致大量线程挂起,很可能会导致系统宕机,所以如果遇到紧急情况,需要于线编译,请提出申请,由项目组安排维护组和DBA协助,随时监控锁的情况,这样就没问题。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 品管 工具 QC 七大 手法 BSSQC 数据库连接 事务管理 专题