??xml version="1.0" encoding="utf-8" standalone="yes"?>
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext-*.xml");
IXXXService xxxservice = (IXXXService ) context
.getBean("xxxservice ");
q是一D很典型的加载?br />
然而,正是q种看似到处都是的加载却为后面的BUG埋下伏笔?br />
xxxservice是具体的业务c,它向下与DAO依赖q控制着事务Q这里代表了一个经典而且单的serviceQ具体配|略去,值得一提的是scopeQ这里没有指定,默认的是单例?br />
一切都是那么顺利,像这Lservice代码写的应该不下几百个,可能怽写的更多Q过E依然很陉Q修改完毕。测试,再测试。什么?ORA-12519错误Q见|我打造的q套L易快速的SSH2框架已经在多个项目好评无Cl考验了,写了不下几百ơ的service居然报ORA-12519错误?br />
q速打开PLSQLQ检查数据库sessionQSelect Count(1) From v$session t Where t.SCHEMANAME='XXX';
随着service的执行,session数在增加Q没有减的意思。是的,当时是q样?br />
解决思\Q这U错误出现在久经考验的框架当中,我心里是相当不安的,居然会有q种低味的错误。整理思\开始分析:q段代码唯一与以前不同的地方是Q我们在web应用中,是通过容器加蝲提供bean的,只有容器启动的时候才会加载xml。那么重点就应该是关注XML的加载方式了?br />
在这里我们用的是ApplicationContext接口。注意看spring文档3.5.1.2.2 在非web应用中优雅地关闭springioc容器。它q里用到的是AbstractApplicationContextQ在取得bean后,再执行一个context.registerShutdownHook();
q里实验一把,ApplicationContextҎAbstractApplicationContextQ执行context.close()。结果出来了Qsession已被正常回收Q真相渐渐Q出水面?/p>
l论Q每ơ加载context的做法相当于每次都生成了一ơ新的spring容器Q在默认单例的情况下Q如果不及时关闭context。service所依赖的DAO当中创徏的dataSource也一直存在(包括所有的单例情况下所生成的类)Q从日志看,service事务辖中的session实已经关闭Q但SessionFactoryq是存在的。只有在容器关闭的情况下Qƈ指定了dataSource实例配置中的destroy-method="close"QdataSource单例才会被释放?br />
spring文档当中对生命周期也描述的很清楚。通过DisposableBean或者指定destroy-method都能很好的释攑֍例对象。而prototypecd的对象需要客L昑ּ的指定释放,释放对象完全是客L控制,spring不负责释放?br />
所以,要改善context的加载方式,量的少多次d载,实在没办法的情况下,一定要记得关闭?br />
最后,写代码的随意性,囄事,不经思考,是造成q种BUG的罪恶根源?/p>
是缺乏一个所见即所得的~辑器。而这ơ,q些烦恼d解决。XMLmind XML Editor!W一ơ发现它的时
候有点相见恨晚的感觉Q它让我的文档写的如此轻松?br /> 不过有一点要注意Q在官网下蝲的XMLmind XML Editor个h版是不支持直接将xml生成的html,pdf{格?/p>
的。还好,目前有xsltprocQfopQopenjadeq些工具支持Q有了这些在windows下也可以转换的工P?/p>
成其他格式也不是什么难事。我目前׃用xsltproc来生成html?/p>
附上XMLmind XML Editor的下载地址http://www.xmlmind.com/xmleditor/persoedition.html
附加上xsltproc的下载地址 http://www.zlatkovic.com/pub/libxml/
再附上docbook的地址http://www.oasis-open.org/docbook/
之前的麻烦统l消失,那么剩下的就是n受它的好处了?/p>
不用wordQ文档也可以写的q么漂亮。docbookQ看W二眼发C依然q是那么好?br />
但是我们在某U用场合的q程中,Z么有时事务处理老是不v作用呢?q里,为您道出原因之一,
首先L一D话
Spring的事务实现采用基?/span>AOP的拦截器来实玎ͼ如果没有在事务配|的时候注明回滚的checked exceptionQ那么只有在发生?/span>unchecked exception的时候,才会q行事务回滚?/span>
有必要先解释一?/span>checked exception?/span>unchecked exceptionQ?/span>
先看?/span>EXCEPTION?/span>JDK文档当中的结?/span>
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
?span lang=EN-US>Unchecked exception: q类异常都是RuntimeException的子c,虽然RuntimeException同样也是Exception的子c,但是它们是特D的?/span>Exception是作?span lang=EN-US>checked Exception 出现的?span lang=EN-US>
所以,除了Error?span lang=EN-US>RuntimeExceptionQ其他剩下的异常都是你需要关心的Q而这些异常类l称?span lang=EN-US>Checked Exception
有了以上的基Q看看我们框架当中的事务属?/span>
<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>
此处Q我们没有指定Q何异常,那么它目前默认处理的是unchecked exception了,再结合我们自w每个项目的模块Q在我们的每个项目当中几乎都定义了自q异常Q这些异帔R是承自ExceptionQ很不幸的是Q我们承的Exception包括自己定义的异常,都是checked exception?/span>
所以,在我们的事务处理机制当中Q事务不用了?/span>
解决办法?/span>2个:
1Q在事务属性后面加上需要回滚的checked exception。比?/span><prop key="save*">PROPAGATION_REQUIRED,-XXXXException</prop>(注意那个"-",对应的是"+")
2, 不改配置文gQ将需要事务回滚的异常l承?/span>unchecked exceptionc,也就?/span>RuntimeException?br>
(nighthawk)
前面提到的另一个版本则是需要基于JBOSS环境的完全版。它的配|相对于Embeddable来说更简单一些。 ?实际上针对这个版本的web应用当中调用EJB3 是无需M额外配置?
然而在此之前我C一D弯路:
比如看到|上一些介l性的文章当中提到需要将{jboss_home}\client 当中的一些包拷到web-inf\lib的下面,然后在初始化InitialContext旉要加上java.naming.factory.initialQjava.naming.factory.url.pkgs{等的参数。这样反而会抛出CommunicationException: Receive timed out异常。实际上JBOSS都已l将初始化环境设|好了?br />以下实例是web环境下调用jboss 下ejb3的客LQ?br />http://www.myjavaserver.com/~nighthawk/EJBClient.war
部v在jboss下的ejb3例子Q以?个客L都是调用的它Q?br />http://www.myjavaserver.com/~nighthawk/MyEJB.jar
web环境下调用Embeddable ejb的客L的实例比较大Q空间不够,不往上放了?br />不过配置h也很单,只需Embeddable版本当中的conf与lib包放在war包的classed与lib下即可?br />以上例子均在jboss-4.0.4.GA下测试过?br /> ©2006 nighthawk.All rights reserved