积累,创造,分享!

BlogJava 首页 新随笔 联系 聚合 管理
  25 Posts :: 13 Stories :: 26 Comments :: 0 Trackbacks

2009年4月16日 #

问题现象:在做web应用时会碰到这种情况,某些地方无法通过web当中的ApplicationContext来获得springIOC容器提供的bean,比如提供给外界的webservice接口,这个时候就需要手工通过ClassPathXmlApplicationContext等方式来获取ApplicationContext,代码如下:
ApplicationContext context = new ClassPathXmlApplicationContext(
    "applicationContext-*.xml");
IXXXService xxxservice = (IXXXService ) context
    .getBean("xxxservice ");
这是一段很典型的加载。
然而,正是这种看似到处都是的加载却为后面的BUG埋下伏笔。
xxxservice是具体的业务类,它向下与DAO依赖并控制着事务,这里代表了一个经典而且简单的service,具体配置略去,值得一提的是scope,这里没有指定,默认的是单例。
一切都是那么顺利,像这样的service代码写的应该不下几百个,可能诸位写的更多,过程依然很陶醉,修改完毕。测试,再测试。什么?ORA-12519错误!见鬼,我打造的这套号称简易快速的SSH2框架已经在多个项目好评无数久经考验了,写了不下几百次的service居然报ORA-12519错误。
迅速打开PLSQL,检查数据库session,Select Count(1) From v$session t Where t.SCHEMANAME='XXX';
随着service的执行,session数在增加,没有减少的意思。是的,当时就是这样。

解决思路:这种错误出现在久经考验的框架当中,我心里是相当不安的,居然会有这种低级趣味的错误。整理思路开始分析:这段代码唯一与以前不同的地方就是,我们在web应用中,是通过容器加载提供bean的,只有容器启动的时候才会加载xml。那么重点就应该是关注XML的加载方式了。
在这里我们用的是ApplicationContext接口。注意看spring文档3.5.1.2.2 在非web应用中优雅地关闭springioc容器。它这里用到的是AbstractApplicationContext,在取得bean后,再执行一个context.registerShutdownHook();
这里实验一把,将ApplicationContext改成AbstractApplicationContext,执行context.close()。结果出来了,session已被正常回收,真相渐渐浮出水面。


结论:每次加载context的做法相当于每次都生成了一次新的spring容器,在默认单例的情况下,如果不及时关闭context。service所依赖的DAO当中创建的dataSource也一直存在(包括所有的单例情况下所生成的类),从日志看,service事务管辖中的session确实已经关闭,但SessionFactory还是存在的。只有在容器关闭的情况下,并指定了dataSource实例配置中的destroy-method="close",dataSource单例才会被释放。
spring文档当中对生命周期也描述的很清楚。通过DisposableBean或者指定destroy-method都能很好的释放单例对象。而prototype类型的对象需要客户端显式的指定释放,释放对象完全是客户端控制,spring不负责释放。
所以,要改善context的加载方式,尽量的少多次去加载,实在没办法的情况下,一定要记得关闭。
最后,写代码的随意性,图省事,不经思考,是造成这种BUG的罪恶根源。

posted @ 2009-04-16 17:27 nighthawk 阅读(2706) | 评论 (3)编辑 收藏

2008年3月23日 #

     摘要: 关注领域模型有一段时间了,不论是分析阶段的还是设计阶段的。
其实领域模型的概念很早就有了,但是其概念非常容易被人混淆,首先我们要明确一下这个词的语境:
它在软件开发的分析与设计的两个阶段分别代表不同的含义。
  阅读全文
posted @ 2008-03-23 00:01 nighthawk 阅读(1631) | 评论 (0)编辑 收藏

2008年3月22日 #

至于docbook的好处,我也不多说了,就跟吃菜一样,尝过了就知道到底有几好
趁目前有空,部门内部准备补充一下之前缺乏的技术文档。利用这次机会,我再次收想到了docbook。
记得第一次接触docbook的时候,还是3年前的时候了,可惜那个时候没有坚持使用下来。
当初抛弃它的原因是多方面的,缺乏恒心是一方面,配置烦琐也是一方面,另外还有一个很重要的原因就

是缺乏一个所见即所得的编辑器。而这次,这些烦恼彻底解决。XMLmind XML Editor!第一次发现它的时

候有点相见恨晚的感觉,它让我的文档写的如此轻松。
不过有一点要注意,在官网下载的XMLmind XML Editor个人版是不支持直接将xml生成的html,pdf等格式

的。还好,目前有xsltproc,fop,openjade这些工具支持,有了这些在windows下也可以转换的工具,生

成其他格式也不是什么难事。我目前就使用xsltproc来生成html。

附上XMLmind XML Editor的下载地址http://www.xmlmind.com/xmleditor/persoedition.html
附加上xsltproc的下载地址 http://www.zlatkovic.com/pub/libxml/
再附上docbook的地址http://www.oasis-open.org/docbook/

之前的麻烦统统消失,那么剩下的就是享受它的好处了。

不用word,文档也可以写的这么漂亮。docbook,看第二眼发现你依然还是那么好。

posted @ 2008-03-22 18:21 nighthawk 阅读(357) | 评论 (0)编辑 收藏

2007年7月9日 #

在目前使用的现有框架当中,利用springAOP机制来控制事务处理是目前最流行的一种控制事务的方式。

但是我们在某种使用场合的过程中,为什么有时事务处理老是不起作用呢?这里,为您道出原因之一,

首先请看一段话

Spring的事务实现采用基于AOP的拦截器来实现,如果没有在事务配置的时候注明回滚的checked exception,那么只有在发生了unchecked exception的时候,才会进行事务回滚。

有必要先解释一下checked exceptionunchecked exception

先看看EXCEPTIONJDK文档当中的结构

java.lang.Object
  继承者 java.lang.Throwable
      继承者 java.lang.Exception
          继承者 java.lang.RuntimeException
 
Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是特殊的。Exception是作为checked Exception 出现的。
所以,除了ErrorRuntimeException,其他剩下的异常都是你需要关心的,而这些异常类统称为Checked Exception
 

有了以上的基础,看看我们框架当中的事务属性

<property name="transactionAttributes">

                     <props>

                            <prop key="get*">PROPAGATION_REQUIRED,readOnly </prop>

                            <prop key="save*">PROPAGATION_REQUIRED </prop>

                            <prop key="delete*">PROPAGATION_REQUIRED</prop>

                            <prop key="update*">PROPAGATION_REQUIRED </prop>

                     </props>

 

</property>

 

此处,我们没有指定任何异常,那么它目前默认处理的就是unchecked exception了,再结合我们自身每个项目的模块,在我们的每个项目当中几乎都定义了自己的异常,这些异常都是继承自Exception,很不幸的是,我们继承的Exception包括自己定义的异常,都是checked exception

 

所以,在我们的事务处理机制当中,事务不管用了。

解决办法有2个:

1,在事务属性后面加上需要回滚的checked exception。比如<prop key="save*">PROPAGATION_REQUIRED,-XXXXException</prop>(注意那个"-",对应的是"+")

2, 不改配置文件,将需要事务回滚的异常继承自unchecked exception类,也就是RuntimeException

(nighthawk)

posted @ 2007-07-09 09:32 nighthawk 阅读(2060) | 评论 (3)编辑 收藏

2007年2月13日 #

现在再做2006年的总结,似乎有点晚了,毕竟现在阳历已经是2007年2月份了,不过按照老家的传统,没过春节,那还算2006年。按照总结的惯例,应该是先回顾后展望,所以我也先回顾。这个总结,只谈感受。
06年3月份,开始维护部门的一个新的项目,换了个新的环境,不过对我而言,接触的却不是新的技术。也许现在已经不是追新的阶段了。
做软件的都有个习惯,爱接触新的技术,这几年JAVA层出不穷的框架,技术太多了,让人有点应接不瑕。这些东西要是不接触,有时候还真会被人笑话,毫不例外,我也不落俗套,其实我并不是一个对新鲜事物非常敏感的人,不过有些技术,还是需要了解为好。
06年,接触的依然是struts,依然是hibernate,依然是spring。抽空看了看JSF,EJB3.0。spring和hibernate依然是那么辉煌,而struts,已经开始没落了。webwork2开始抢风头,包括现在的struts2,转眼间,已经不是我们熟悉的struts了,无非是包装过后的webwork2,转眼间,也感觉到了时间的流逝。通宵达旦培训学习struts的时候,已经是3年前了。
06年,接触了领域驱动设计,让我明白除了larman的领域模型,原来还有eric的领域模型,可惜目前,我依然是个学习者,而不是一个实践者。
06年上半年,我虔诚的捧来了martin的重构,可惜到目前为止,那本书还是新的。
06年,也接触了天书般的分析模式。它当之无愧的当选为我的最佳催眠书,以至于我现在不拿着它睡不着,因为它的确让我没看懂。
06年,我依然在看2年前买的UML和模式应用,依然偶尔翻翻1年前买的J2EE核心模式。不过这一年,J2EE核心模式似乎有点辉煌不在了。
头几年,感觉一切都是新的,一切都要学。而这一年,感觉进步远不如前2年了,也许进步更快,我没有发现而已。我一直在告戒自己,学习分析与设计不会有学习语言或者框架那种立竿见影的效果,它是一个积累,一个持续性的过程,我还在等着顿悟分析模式的那一天。
07年,我依然会追随大师们的脚步。
07年,还要继续做点什么。

posted @ 2007-02-13 09:55 nighthawk 阅读(255) | 评论 (2)编辑 收藏

仅列出标题  下一页