BSS_QC_数据库连接和事务管理专题_第1页
BSS_QC_数据库连接和事务管理专题_第2页
BSS_QC_数据库连接和事务管理专题_第3页
BSS_QC_数据库连接和事务管理专题_第4页
BSS_QC_数据库连接和事务管理专题_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、BSS系统中数据库连接的安全使用和事务问题汇总V1.0.1修改日期原因修改人2007-09-30根据zhaoxin的意见,修改了Hibernate的session连接管理刘世伟2007-11-8根据调优组当前的工作,补充了一些内容刘世伟几个名词解释:1、 数据库连接池:众所周知,建立数据库连接是一个昂贵的操作,每次都得花费约0.05s1s的时间,消耗一定的内存资源(Oracle 9i的一个空闲连接约需25MB内存,非空闲连接约需几十MB左右内存),而且一旦到达临界点,系统会陷入资源管理的恶性循环:越来越慢。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连

2、接备用,减少使用时才创建、销毁的消耗。当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。使用连接池后,数据库服务器减少了它并不擅长的连接管理工作,通过池连接的快速复用,可以为客户端提供更大的并发量,内存消耗也在可控范围内波动。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接,控制数据库的压力。我们也可以通过连接池的管理机制监控数据库连接的数量使用情况,为系统开发测试及性能调优提供依据。2、 真实连接:客户端程序直接和数据库建立的Connection,使用完毕需要及时、安全的关闭,否则会导致数据库内存资源泄漏、服务器宕机3、 代理连接:客户端程序从连接池获取的

3、Connection,它实际上是封装了真实连接,提供和真实连接相同的功能,使用完毕也需要及时、安全的关闭,否则连接池中的连接得不到释放,会导致连接池中可用的空闲连接越来越少。当然,由于存在连接池的控制,数据库不会因此而宕机。一、BSS数据库连接管理现状:BSS系统中对数据库连接的管理,是统一通过数据源(DataSource)管理的,存在连接池和单连接两种方式的数据源(详情参考modelxxx.jar中的xxxDatabase.xml文件)1、 连接池数据源,命名方式为“xxxDataSource”,BSS采用了apache的开源池mons.dbcp.BasicDataSource,应用程序获取

4、的是apache连接池的代理连接(connectionProxy),非真实连接。2、 单连接数据源,命名方式为“xxxDataSourceNoPool”,BSS采用了Spring框架的org.springframework.jdbc.datasource.DriverManagerDataSource,程序获取的是真实的数据库连接。二、BSS系统中对数据源的使用1、 Hibernate的SessionFactory,使用的是连接池数据源,在配置文件中一般命名为“xxxSessionFactory”,而且Hibernate本身包含一个简单的连接池hibernate.connection,但性能和

5、功能不如apache的。2、 Spring的JdbcTemplate,根据其使用数据源是否为连接池,命名方式也不同,配置文件中对使用连接池数据源的命名为“xxxJDBC”,使用单连接数据源的命名为“xxxJDBCNoPool”三、应用程序中对连接的使用BSS程序中使用Hibernate的session和JdbcTemplate提供的通用方法一般是够用的,但某些场景下如执行oracle特性的SQL语句或存储过程,需要获取真实数据库连接,现在主要使用以下几种方式:1、 Hibernate中,通过getSession().connection(),此时获取的是连接是根据其数据源决定的,如果通过连接池

6、中获取,则是代理连接,否则是真实数据库连接,但注意,无论如何都不能用conn.close()语句显示关闭的;这时候的conn其实是被session管理了,Hibernate会在Session的事务提交或回滚的时候,自动把连接放回池中,如果我们主动关了,会抛异常。2、 JdbcTemplate中,通过jdbc.getDataSource().getConnection(),此时获取的连接是根据其数据源决定的,如果jdbc.getDataSource()返回的是连接池数据源,则连接是连接池的连接代理(重载了真实连接的close方法),需要从代理连接中再次获取真实连接,见下面的a段落;如果返回的是单

7、连接的数据源,则返回的是真实连接。这2种连接都需要显式的close关闭,前者表示把连接还回连接池继续使用,后者表示真正关闭连接,释放数据库内存。a) 对JdbcTemplate中返回代理连接的情况,由于是连接代理,对Oracle的Blob和Clob大数据对象,在CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION)的时候,会抛ClassCastException,此时需要获取真实的物理连接,方法如下:i. 设置DataSource中连接池的accessToUnderlyingConnectionAllowed属性的值为true,表示允许从

8、连接代理中获取物理连接;ii. 对apache的BasicDataSource,可通过mons.dbcp.DelegatingConnection的getDelegate()方法获取真实连接。iii. 注意,通过连接池代理连接而获取的真实连接一定不能直接关闭,否则连接池就没有意义了,最好把这种情况下的获取物理连接创建Clob用方法屏蔽掉,防止被误关闭。代码扫描后发现系统中普遍存在的问题:1、对打开的数据库资源conn、ps、rs,主动写了close语句,但是没有写在finally语句块里面,一旦发生异常,那么close语句就会被旁路,导致资源得不到释放。2、没有主动写close语句,当然这个是

9、存在一些争议的,请看以下解释:    a、如果不使用连接池机制, 关闭connection, 会自动关闭resultset和statement的,程序中可以不显示关闭;    b、如果使用连接池, 所谓的关闭connection, 其实是将连接返回给了连接池,连接对象依然存在, 实际上不是物理关闭,因此,必须显示的关闭resultset和statement,否则连接池中连接上的rs和ps会越来越多。3、单独写了close的语句块,到没什么问题,看着不舒服罢了。附件是代码中问题的位置,请

10、详看。建议:我们系统有使用连接池和单独创建连接的,所以保险起见,resultset和statment(PreparedStatement、CallableStatement)一定在finally语句里面主动保持先后次序close掉,在此贴一下示例程序。Connection con = null;PreparedStatement ps = null;ResultSet rs = null;try .catch (SQLException ex).finally    try         if

11、(rs!=null)            rs.close();        catch (SQLException ex)         /错误处理        try         if(ps!=null) 

12、;           ps.close();        catch (SQLException ex)         /错误处理        try        if(con!=null) /注意:Hibernate中

13、得到的conn不能关闭。            con.close();        catch (SQLException ex)         /错误处理     数据库事务管理现状:BSS中采用了Spring的声明式事务管理,在配置文件中通过对象或方法的名称通配事务的加载与否。由于存在以上的数据库连接管理方式

14、,所以对数据库的事务管理也是存在多种方式:1、 Hibernate的session2、 JdbcTemplate3、 通过session或jdbcTemplate获取的Connection,一般直接执行sql语句和存储过程存在的问题:1、事务回滚规则只有DAOException(部分),缺BssException        现在BMO中规范抛出BssException,一旦BMO方法中出现异常,现在的配置是事务不回滚的,导致前后数据不完整。       

15、; 建议,spring事务配置里面加入强制回滚模式匹配: -mon.BssException,如下:                <property name="transactionAttribute">                 

16、60; <value>PROPAGATION_REQUIRED,-mon.DAOException,-mon.BssException</value>                </property>  EJB事务回滚规则:    1、如果bean抛出RuntimeException,容器会自动回滚事务,并且在外面包装一个RemoteException抛出。 

17、;   2、如果bean抛出其他的异常,容器不会做任何处理,除非强制定义。 2、事务拦截粒度比较粗,定义在类级别而不是方法级别        事务拦截器的配置在bean的名称上,该bean下所有的方法都按照同一种事务模式        象readonly的事务隔离模式,对只查询不修改的方法,性能提高比较大,但需要更改拦截器,定义在方法级别。        此

18、条只涉及性能,影响不是很大,可酌情。3、EJB和spring的事务传递问题        如果BMO中spring不加载事务,被EJB包装后,发现EJB的事务不能传递给spring,EJB事务回滚了,但是spring管理bean的事务仍旧提交了,原因待详查,初步分析是ejb容器和spring容器事务不能透传,按照EJB规范,CMT(容器管理的事务)内部是不能有嵌套事务的。当前为规避此种情况,建议所有的BMO,如果需要事务的,名称一律按照规范以“Manager”“DAO”结尾。调优组正在组织力量集中解决这个问题,初步思路是启用EJB BMT(Bean 管理事务),使用websphere的事务管理和连接池存储过程和Java事务的嵌套问题:在一个bmo中同时调用几个dao,dao中分别用hibernate、jdbc和存储过程完成insert或update操作,事务是可以完整的,不过需要注意2点:一是存储过程里面不能有commit和rollback二是dao调用存储过程后,dao中也不要写commit和rollback,只要close就可以,由事务控制自动提交,除非捕捉到bssexception

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论