﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-diggbag</title><link>http://www.blogjava.net/diggbag/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 17:19:59 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2026 17:19:59 GMT</pubDate><ttl>60</ttl><item><title>用jstack跟踪cpu占用率的java线程</title><link>http://www.blogjava.net/diggbag/articles/jstack.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Wed, 01 Aug 2012 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/jstack.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/384536.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/jstack.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/384536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/384536.html</trackback:ping><description><![CDATA[<p>以下方法在centOS下执行通过：<br />1.先定位占用cpu高的进程</p>
<p>top </p>
<p>2.使用以下命令</p>
<p>ps p 14766 -L -o pcpu,pid,tid,time,tname,stat,psr | sort -n -k1 -r</p>
<p>其中14766是刚才1中cpu占用率高的进程pid</p>
<p>3.<span style="font-family: 'Courier New'">2.4 32525 32537 01:58:41 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 6 <br />0.8 32525&nbsp; 1771 00:43:12 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.8 32525&nbsp; 1769 00:39:46 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.7 32525 12324 00:33:36 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.5 32525&nbsp; 1772 00:27:50 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.5 32525&nbsp; 1768 00:25:45 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.4 32525 30760 00:19:13 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.4 32525&nbsp; 1773 00:22:36 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.4 32525&nbsp; 1770 00:20:25 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.3 32525 32385 00:00:10 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.1 32525 31668 00:00:03 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.1 32525 <span style="color: #ff0000">31667</span> 00:00:03 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 0 <br />0.1 32525&nbsp; 1790 00:07:10 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; 1</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 'Courier New'">其中第3个结果就是此进程中有问题的线程nid</span></p>
<p><span style="font-family: 'Courier New'">4.通过jstack命令dump出堆栈</span></p>
<p><span style="font-family: 'Courier New'">"AppController_ThreadPool_L2_Pool Thread" daemon prio=10 tid=0x0000000051c2b000 nid=<strong><u><span style="color: #ff0000">0x7bb3</span></u></strong> in Object.wait() [0x000000005e3c5000] <br />&nbsp;&nbsp; java.lang.Thread.State: TIMED_WAITING (on object monitor) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at java.lang.Object.wait(Native Method) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.company.threadpool.ThreadPoolImpl$PoolThread.run(ThreadPoolImpl.java:142) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - locked &lt;0x00002aaca30341a8&gt; (a org.company.threadpool.ThreadPoolImpl$PoolThread)</span></p>
<p><span style="font-family: 'Courier New'">其中的nid就是线程的编码，只不过是经过了16进制的转换。</span></p>
<p><span style="font-family: 'Courier New'">即十进制的31776对应的十六进制)0x7bb3，定位到线程后一切好办。</span>&nbsp;</p><img src ="http://www.blogjava.net/diggbag/aggbug/384536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-08-01 17:22 <a href="http://www.blogjava.net/diggbag/articles/jstack.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于在JAXB中使用泛型的问题</title><link>http://www.blogjava.net/diggbag/articles/JAXB.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Thu, 12 Jul 2012 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/JAXB.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/382913.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/JAXB.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/382913.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/382913.html</trackback:ping><description><![CDATA[<p>1.在使用jaxbMarshaller生成xml的过程中，有java bean如下使用到了泛型：</p>
<p>@XmlRootElement(name = "ReturnInfo")<br />@XmlType()<br />public class ReturnInfo&lt;T&gt; {</p>
<p>private List&lt;T&gt; resultList;</p>
<p>&nbsp;public List&lt;T&gt; getResultList() {</p>
<p>&nbsp;&nbsp;return resultList;<br />&nbsp;}</p>
<p>&nbsp;public void setResultList(List&lt;T&gt; resultList) {</p>
<p>&nbsp;&nbsp;this.resultList = resultList;<br />&nbsp;}</p>
<p>}</p>
<p>2.在最初测试的时候jaxbMarshaller报异常，无法找到处理泛型的办法。</p>
<p>3.在使用jaxb时需要在java bean打上@XmlSeeAlso(MultiQueryInfo.class)注释，作用就是是在jaxb绑定一个class时候可以使用</p>
<p>其他的class，在jaxb使用多态的时候都需要用到此标签；其中括号中可以添加多个class,如@XmlSeeAlso(A.class,B.class)</p>
<p>4.在客户端的bean中也需要用到此注释，否则同样报转换错误：</p>
<p>Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.jd.fms.adsettlement.client.domain.MultiQueryInfo<br /></p><img src ="http://www.blogjava.net/diggbag/aggbug/382913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-07-12 19:04 <a href="http://www.blogjava.net/diggbag/articles/JAXB.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决m2eclipse插件引起的pom.xml校验错误</title><link>http://www.blogjava.net/diggbag/articles/375156.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Wed, 18 Apr 2012 10:19:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/375156.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/375156.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/375156.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/375156.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/375156.html</trackback:ping><description><![CDATA[<p>1.pom.xml文件报Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-resources-plugin:2.2:resources (execution: default-resources, phase: process-resources)&nbsp;pom.xml&nbsp;/testMaven-common&nbsp;line 3&nbsp;Maven Project Build Lifecycle Mapping Problem</p>
<p>2.导致此错误是m2eclipse插件0.12及之前的版本在Eclipse 内执行了一系列的生命周期引起冲突导致的，如果你的maven报此类错误，而又用到了maven-resources-plugin这个插件，那么请按你的项目pom.xml中加上</p>
<p>&lt;plugin&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.eclipse.m2e&lt;/groupId&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;lifecycle-mapping&lt;/artifactId&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;1.0.0&lt;/version&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;lifecycleMappingMetadata&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pluginExecutions&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pluginExecution&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pluginExecutionFilter&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;versionRange&gt;[1.2,)&lt;/versionRange&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goals&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;goal&gt;resources&lt;/goal&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;goal&gt;testResources&lt;/goal&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/goals&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/pluginExecutionFilter&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ignore /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/action&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/pluginExecution&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/pluginExecutions&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/lifecycleMappingMetadata&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/plugin&gt;</p>
<p>解决冲突，具体原因参看<a href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered">http://wiki.eclipse.org/M2E_plugin_execution_not_covered</a></p>
<p><br />&nbsp;</p><img src ="http://www.blogjava.net/diggbag/aggbug/375156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-04-18 18:19 <a href="http://www.blogjava.net/diggbag/articles/375156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为Java添加动态语言能力：通过spring配置使用groovy</title><link>http://www.blogjava.net/diggbag/articles/373730.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Tue, 10 Apr 2012 09:55:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/373730.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/373730.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/373730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/373730.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/373730.html</trackback:ping><description><![CDATA[<p>1.使用背景：项目中想使用规则引擎，调研后发现流行的开源规则引擎都比较重量级，考虑到项目只需要通过配置文件设定规则集，故使用java动态使用groovy即可达到目的；<br /></p>
<p>2.通过以下方式配置spring使用groovy，和采用java编程没有太大区别，groovy提供较平顺的从java过来的学习曲线，下面的例子中的groovy类活生生就是一个java类，只不过是写在xml文件中的java类罢了；<br /></p>
<p>3.spring通过org.springframework.scripting.groovy.GroovyScriptFactory类反射生成groovy类，由于使用到jdk的动态代理，所以所有用groovy定义的类必须实现java定义的接口，这是可以运行的关键；</p>
<p>4.配置spring.xml</p>
<p>&lt;beans xmlns="<a href="http://www.springframework.org/schema/beans" kesrc="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"<br />&nbsp;&nbsp;xmlns:lang="<a href="http://www.springframework.org/schema/lang" kesrc="http://www.springframework.org/schema/lang">http://www.springframework.org/schema/lang</a>"<br />&nbsp;xsi:schemaLocation="<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.springframework.org/schema/beans" kesrc="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.springframework.org/schema/beans/spring-beans.xsd" kesrc="http://www.springframework.org/schema/beans/spring-beans.xsd">http://www.springframework.org/schema/beans/spring-beans.xsd</a><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.springframework.org/schema/lang" kesrc="http://www.springframework.org/schema/lang">http://www.springframework.org/schema/lang</a> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.springframework.org/schema/lang/spring-lang-2.5.xsd" kesrc="http://www.springframework.org/schema/lang/spring-lang-2.5.xsd">http://www.springframework.org/schema/lang/spring-lang-2.5.xsd</a><br />&nbsp; "<br />&nbsp;default-autowire="byName"&gt;</p>
<p>此文件头必不可少，否则无法识别lang标签；</p>
<p>&lt;lang:groovy id="groovyHello" &gt;<br />&nbsp; &lt;lang:inline-script&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;![CDATA[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; package com.jd.fms;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import com.jd.fms.netty.GroovyHelloWorld;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public class TestGroovyHelloWorld implements GroovyHelloWorld{ <br />&nbsp;&nbsp;&nbsp;&nbsp;public void doit(){ <br />&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("hello world");<br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ]]&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/lang:inline-script&gt;<br />&nbsp;&lt;/lang:groovy&gt;</p>
<p>采用lang:groovy定义groovy片段，当然也可以采用</p><pre class="displaycode">&lt;lang:groovy id=" script-source="...."&gt;的方式引入文件。</pre><pre class="displaycode">不要忘记的是在工程中定义GroovyHelloWorld的接口，该接口需要实现一个doit方法。</pre><pre class="displaycode">5.项目中直接通过</pre><pre class="displaycode">@Autowired
&nbsp;GroovyHelloWorld groovyHelloWorld;</pre><pre class="displaycode">调用即可；</pre><pre class="displaycode">6.groovy为java提供了很好的动态语言能力，如果项目没有必要使用太重量级的规则引擎，</pre><pre class="displaycode">那么使用动态语言让业务人员直接配置也不失为一个好方法。</pre>
<p>&nbsp;</p><img src ="http://www.blogjava.net/diggbag/aggbug/373730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-04-10 17:55 <a href="http://www.blogjava.net/diggbag/articles/373730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于mybatis的batch模式性能测试及结论</title><link>http://www.blogjava.net/diggbag/articles/mybatis.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Thu, 16 Feb 2012 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/mybatis.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/370130.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/mybatis.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/370130.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/370130.html</trackback:ping><description><![CDATA[<div style="text-indent: 2em">近日在公司项目中，使用到spring+mybatis的架构，特对mybatis的batch模式做了相关研究，得出以下结论：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 1.Mybatis内置的ExecutorType有3种，默认的是simple，该模式下它为每个语句的执行创建一个新的预处理语句，单条提交sql；而batch模式重复使用已经预处理的语句，</div>
<div style="text-indent: 2em">并且批量执行所有更新语句，显然batch性能将更优；</div>
<div style="text-indent: 2em">&nbsp;</div>
<div style="text-indent: 2em">2.但<font style="background-color: #fbfbfb">batch模式也有自己的问题，比如在Insert操作时，在事务没有提交之前，是没有办法获取到自增的id，这在某型情形下是不符合业务要求的；</font></div>
<div style="text-indent: 2em"><font style="background-color: #fbfbfb"></font>&nbsp;</div>
<div style="text-indent: 2em"><font style="background-color: #fbfbfb">3.</font>&nbsp;在测试中使用simple模式提交10000条数据，时间为18248 毫秒，batch模式为5023 ，性能提高70%；</div>
<div style="text-indent: 2em">&nbsp;</div>
<div style="text-indent: 2em">4.通过走码和研读spring相关文件发现，<font color="#ff0000">在同一事务中batch模式和simple模式之间无法转换</font>，由于本项目一开始选择了simple模式，所以碰到需要批量更新时，只能在单独的事务中进行；</div>
<div style="text-indent: 2em">&nbsp;</div>
<div style="text-indent: 2em">5.在代码中使用batch模式可以使用以下方式：</div>
<div style="text-indent: 2em">&nbsp;</div>
<div style="text-indent: 2em">//从spring注入原有的sqlSessionTemplate</div>
<div style="text-indent: 2em">
<div>@Autowired</div>
<div>private&nbsp;SqlSessionTemplate&nbsp;sqlSessionTemplate;</div>
<div>&nbsp;</div>
<div>
<div>public&nbsp;void&nbsp;testInsertBatchByTrue()&nbsp;{</div>
<div>&nbsp;</div>
<div>//新获取一个模式为<font color="#ff0000">BATCH，</font>自动提交为false的session</div>
<div><font color="#ff0000">//<font color="#000000">如果自动提交设置为</font>true</font><font color="#000000">,将无法控制提交的条数，改为最后统一提交，可能导致内存溢出</font></div>
<div style="text-indent: 4em">SqlSession&nbsp;session&nbsp;=&nbsp;sqlSessionTemplate.getSqlSessionFactory().openSession(</div>
<blockquote style="margin-right: 0px" dir="ltr">
<div><font color="#ff0000">ExecutorType.BATCH,&nbsp;false</font>);</div></blockquote>
<div>//通过新的session获取mapper</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;fooMapper&nbsp;=&nbsp;session.getMapper(FooMapper.class);</div>
<div></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;size&nbsp;=&nbsp;10000;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;size;&nbsp;i++)&nbsp;{</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foo&nbsp;foo&nbsp;=&nbsp;new&nbsp;Foo();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo.setName(String.valueOf(System.currentTimeMillis()));</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fooMapper.insert(foo);</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;%&nbsp;1000&nbsp;==&nbsp;0&nbsp;||&nbsp;i&nbsp;==&nbsp;size&nbsp;-&nbsp;1)&nbsp;{</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//手动每1000个一提交，提交后无法回滚</div>
<blockquote style="margin-right: 0px" dir="ltr">
<blockquote style="margin-right: 0px" dir="ltr">
<div style="text-indent: 8em"><font color="#ff0000">session.commit();</font></div></blockquote></blockquote>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//清理缓存，防止溢出</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.clearCache();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</div>
<blockquote style="margin-right: 0px" dir="ltr">
<blockquote style="margin-right: 0px" dir="ltr">
<div style="text-indent: 4em"><font color="#ff0000">//没有提交的数据可以回滚</font></div></blockquote></blockquote>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.rollback();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;finally&nbsp;{</div>
<blockquote style="margin-right: 0px" dir="ltr">
<blockquote style="margin-right: 0px" dir="ltr">
<div style="text-indent: 8em"><font color="#ff0000">session.close();</font></div></blockquote></blockquote>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<div>&nbsp;</div>
<div>6.上述代码没有使用spring的事务，改动手动控制，<font color="#ff0000">如果和原spring事务一起使用，将无法回滚，</font>必须注意，最好单独使用；<br /><br /></div></div></div><img src ="http://www.blogjava.net/diggbag/aggbug/370130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-02-16 17:40 <a href="http://www.blogjava.net/diggbag/articles/mybatis.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用spring AOP后注入失败的解决方法</title><link>http://www.blogjava.net/diggbag/articles/369228.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Thu, 02 Feb 2012 04:14:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/369228.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/369228.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/369228.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/369228.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/369228.html</trackback:ping><description><![CDATA[<p>项目框架是struts2+spring，在未使用AOP机制前，在action层注入的service是没有问题的，但是当尝试在action层使用AOP机制拦截相关异常时，会出现注入失败的问题，出现空指针异常。<br /><br />问题分析：原因是一般struts2+spring应用中，spring的插件只负责为action的ioc部分，但并没有进行功能加强，即采用代理的机制，所有的action还是使用struts2进行管理，<br />在使用AOP后，这些action需要由spring进行管理，如果没有由spring进行代理，将出现注入失败。<br /><br />解决办法：在每个action前加上@Component("loginAction") @Scope("prototype")，在struts的配置中使用loginAction的名字进行配置，@Scope用于声明action使用多实例，这样AOP可以进行正常注入</p><img src ="http://www.blogjava.net/diggbag/aggbug/369228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2012-02-02 12:14 <a href="http://www.blogjava.net/diggbag/articles/369228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用apache cxf 发布RESTful webservice</title><link>http://www.blogjava.net/diggbag/articles/361912.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Mon, 24 Oct 2011 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/361912.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/361912.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/361912.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/361912.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/361912.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1&nbsp;RESTful简要介绍RESTful风格的WebService之所以当下如此流行，是由于其相对于SOAP风格的WebService更简洁、更轻量级，REST风格的WebService传输的是JSON或极其简洁的XML，因而其效率和性能都比较理想。RESTful风格的WebService主张重用HTTP协议，面向资源编程（ROA）。扼要的说，RESTful风格WebServic...&nbsp;&nbsp;<a href='http://www.blogjava.net/diggbag/articles/361912.html'>阅读全文</a><img src ="http://www.blogjava.net/diggbag/aggbug/361912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2011-10-24 17:27 <a href="http://www.blogjava.net/diggbag/articles/361912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RESTful webservice 和 SOAP webserivce 对比及区别</title><link>http://www.blogjava.net/diggbag/articles/361703.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Fri, 21 Oct 2011 03:05:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/361703.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/361703.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/361703.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/361703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/361703.html</trackback:ping><description><![CDATA[<p><a name="6.1.接口抽象|outline"><span class="smalltitle">接口抽象</span></a></p>
<p>RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力，而不同的是，SOAP 应用都通过定义自己个性化的接口方法来抽象 Web 服务，这更像我们经常谈到的 RPC。例如本例中的 getUserList 与 getUserByName 方法。</p>
<p>RESTful Web 服务使用标准的 HTTP 方法优势，从大的方面来讲：标准化的 HTTP 操作方法，结合其他的标准化技术，如 URI，HTML，XML 等，将会极大提高系统与系统之间整合的互操作能力。尤其在 Web 应用领域，RESTful Web 服务所表达的这种抽象能力更加贴近 Web 本身的工作方式，也更加自然。</p>
<p>同时，使用标准 HTTP 方法实现的 RRESTful Web 服务也带来了 HTTP 方法本身的一些优势：</p>
<ul><li><strong><em>无状态性（Stateless）</em> </strong></li></ul>
<p>HTTP 协议从本质上说是一种无状态的协议，客户端发出的 HTTP 请求之间可以相互隔离，不存在相互的状态依赖。基于 HTTP 的 ROA，以非常自然的方式来实现无状态服务请求处理逻辑。对于分布式的应用而言，任意给定的两个服务请求 Request 1 与 Request 2, 由于它们之间并没有相互之间的状态依赖，就不需要对它们进行相互协作处理，其结果是：Request 1 与 Request 2 可以在任何的服务器上执行，这样的应用很容易在服务器端支持负载平衡 (load-balance)。</p>
<ul><li><strong><em>安全操作与幂指相等特性（Safety /Idempotence）</em> </strong></li></ul>
<p>HTTP 的 GET、HEAD 请求本质上应该是安全的调用，即：GET、HEAD 调用不会有任何的副作用，不会造成服务器端状态的改变。对于服务器来说，客户端对某一 URI 做 n 次的 GET、HAED 调用，其状态与没有做调用是一样的，不会发生任何的改变。</p>
<p>HTTP 的 PUT、DELTE 调用，具有幂指相等特性 , 即：客户端对某一 URI 做 n 次的 PUT、DELTE 调用，其效果与做一次的调用是一样的。HTTP 的 GET、HEAD 方法也具有幂指相等特性。</p>
<p>HTTP 这些标准方法在原则上保证你的分布式系统具有这些特性，以帮助构建更加健壮的分布式系统。</p>
<p><a name="6.2.安全控制|outline"><span class="smalltitle">安全控制</span></a></p>
<p>为了说明问题，基于上面的在线用户管理系统，我们给定以下场景：</p>
<p>参考一开始我们给出的用例图，对于客户端 Client2，我们只希望它能以只读的方式访问 User 和 User List 资源，而 Client1 具有访问所有资源的所有权限。</p>
<p>如何做这样的安全控制？</p>
<p>通行的做法是：所有从客户端 Client2 发出的 HTTP 请求都经过代理服务器 (Proxy Server)。代理服务器制定安全策略：所有经过该代理的访问 User 和 User List 资源的请求只具有读取权限，即：允许 GET/HEAD 操作，而像具有写权限的 PUT/DELTE 是不被允许的。</p>
<p>如果对于 REST，我们看看这样的安全策略是如何部署的。如下图所示：</p><br /><a name="6.2.1.图 4. REST 与代理服务器 (Proxy Servers)|outline"><strong>图 4. REST 与代理服务器 (Proxy Servers)</strong></a><br /><img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/4.jpg" width="547" height="187" /> <br />
<p>一般代理服务器的实现根据 (URI, HTTP Method) 两元组来决定 HTTP 请求的安全合法性。</p>
<p>当发现类似于（http://localhost:8182/v1/users/{username}，DELETE）这样的请求时，予以拒绝。</p>
<p>对于 SOAP，如果我们想借助于既有的代理服务器进行安全控制，会比较尴尬，如下图：</p><br /><a name="6.2.2.图 5. SOAP 与代理服务器 (Proxy Servers)|outline"><strong>图 5. SOAP 与代理服务器 (Proxy Servers)</strong></a><br /><img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/5.jpg" width="569" height="206" /> <br />
<p>所有的 SOAP 消息经过代理服务器，只能看到（<code>http://localhost:8182/v1/soap/servlet/messagerouter</code>, HTTP POST）这样的信息，如果代理服务器想知道当前的 HTTP 请求具体做的是什么，必须对 SOAP 的消息体解码，这样的话，意味着要求第三方的代理服务器需要理解当前的 SOAP 消息语义，而这种 SOAP 应用与代理服务器之间的紧耦合关系是不合理的。</p>
<p><a name="6.3.关于缓存|outline"><span class="smalltitle">关于缓存</span></a></p>
<p>众所周知，对于基于网络的分布式应用，网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销，这是每一个构建分布式网络应用的开发人员必须考虑的问题。</p>
<p>HTTP 协议带条件的 HTTP GET 请求 (Conditional GET) 被设计用来节省客户端与服务器之间网络传输带来的开销，这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 ) 提供了可能。HTTP 协议通过 HTTP HEADER 域：If-Modified-Since/Last- Modified，If-None-Match/ETag 实现带条件的 GET 请求。</p>
<p>REST 的应用可以充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET 请求给服务器获得内容后，该内容可能被缓存服务器 (Cache Server) 缓存。当下一次客户端请求同样的资源时，缓存可以直接给出响应，而不需要请求远程的服务器获得。而这一切对客户端来说都是透明的。</p><br /><a name="6.3.1.图 6. REST 与缓存服务器 (Cache Server)|outline"><strong>图 6. REST 与缓存服务器 (Cache Server)</strong></a><br /><img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/6.jpg" width="530" height="204" /> <br />
<p>而对于 SOAP，情况又是怎样的呢？</p>
<p>使用 HTTP 协议的 SOAP，由于其设计原则上并不像 REST 那样强调与 Web 的工作方式相一致，所以，基于 SOAP 应用很难充分发挥 HTTP 本身的缓存能力。</p><br /><a name="6.3.2.图 7. SOAP 与缓存服务器 (Cache Server)|outline"><strong>图 7. SOAP 与缓存服务器 (Cache Server)</strong></a><br /><img alt="REST" src="http://www.ibm.com/developerworks/cn/webservices/0907_rest_soap/images/7.jpg" width="569" height="115" /> <br />
<p>两个因素决定了基于 SOAP 应用的缓存机制要远比 REST 复杂：</p>
<p>其一、所有经过缓存服务器的 SOAP 消息总是 HTTP POST，缓存服务器如果不解码 SOAP 消息体，没法知道该 HTTP 请求是否是想从服务器获得数据。</p>
<p>其二、SOAP 消息所使用的 URI 总是指向 SOAP 的服务器，如本文例子中的 <code>http://localhost:8182/v1/soap/servlet/messagerouter</code>，这并没有表达真实的资源 URI，其结果是缓存服务器根本不知道那个资源正在被请求，更不用谈进行缓存处理。</p>
<p><a name="6.4.关于连接性|outline"><span class="smalltitle">关于连接性</span></a></p>
<p>在一个纯的 SOAP 应用中，URI 本质上除了用来指示 SOAP 服务器外，本身没有任何意义。与 REST 的不同的是，无法通过 URI 驱动 SOAP 方法调用。例如在我们的例子中，当我们通过</p>
<p>getUserList SOAP 消息获得所有的用户列表后，仍然无法通过既有的信息得到某个具体的用户信息。唯一的方法只有通过 WSDL 的指示，通过调用 getUserByName 获得，getUserList 与 getUserByName 是彼此孤立的。</p>
<p>而对于 REST，情况是完全不同的：通过 <code>http://localhost:8182/v1/users</code> URI 获得用户列表，然后再通过用户列表中所提供的 LINK 属性，例如 <code>&lt;link&gt;http://localhost:8182/v1/users/tester&lt;/link&gt;</code>获得 tester 用户的用户信息。这样的工作方式，非常类似于你在浏览器的某个页面上点击某个 hyperlink, 浏览器帮你自动定向到你想访问的页面，并不依赖任何第三方的信息。</p><br /><br />
<p><a name="7.总结|outline"><span class="atitle">总结</span></a></p>
<p>典型的基于 SOAP 的 Web 服务以操作为中心，每个操作接受 XML 文档作为输入，提供 XML 文档作为输出。在本质上讲，它们是 RPC 风格的。而在遵循 REST 原则的 ROA 应用中，服务是以资源为中心的，对每个资源的操作都是标准化的 HTTP 方法。</p>
<p>本文主要集中在以上的几个方面，对 SOAP 与 REST 进行了对比，可以看到，基于 REST 构建的系统其系统的扩展能力要强于 SOAP，这可以体现在它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面。并且，伴随着 Web Site as Web Services 演进的趋势，基于 REST 设计和实现的简单性和强扩展性，有理由相信，REST 将会成为 Web 服务的一个重要架构实践领域。</p><img src ="http://www.blogjava.net/diggbag/aggbug/361703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2011-10-21 11:05 <a href="http://www.blogjava.net/diggbag/articles/361703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mark:温习一下Oracle中常说的HA、RAC、Datagurad的区别</title><link>http://www.blogjava.net/diggbag/articles/361401.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Mon, 17 Oct 2011 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/361401.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/361401.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/361401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/361401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/361401.html</trackback:ping><description><![CDATA[<strong><font color="#0000ff">HA</font></strong>是High Availability 的首字母组合，翻译过来，可以叫做高可用，或高可用性，高可用（环境）。我觉得应该说HA是一个观念而不是一项或一系列具体技术，就象网格一样。作过系统方案就知道了，评价系统的性能当中就有一项高可用。广义的高可用涉及到系统的各个方面，简单来说，让系统不会中断 运行，就是高可用。包括软件的高可用，硬件的高可用，网络的高可用等等。具体实现的方案包括操作系统的集群，数据库的集群，硬件的冗余，网络的冗余等等。做HA方面的软件，有IBM的HACMP（很多常用AIX的人，常说的HA就指HACMP，乱啊）、SUN的Sun Cluster、HP的MC/SG等。<br /><br />在2000年以前，大家谈HA，大部分时候说的是操作系统一级的双机热备，主流产品当时有IBM HACMP4.1，HP的MC/SG啥版本忘了，sun的系统很多人不用VCS，用的是一个叫dataware的东西。现在很多人眼中的HA也还是这样。时至今日，HA包括的东西可就多了，先不说其他方面，单就数据库，单就Oracle，与HA相关的产品先后有：高级复制（AdvanceRepication)、OPS/RAC(Real Application Cluster）、数据卫士（Data Guard）、oracle流（Oracle Streams）、分区（Oracle Partition）这样数款产品。照这么说，RAC只是HA这个概念下的一个具体产品而已！目前为止，只有RAC和分区是Oracle要收取 licence的，其他的，只要给经验丰富的第三方实施方付一定的规划/设计及部署费用就可以了；当然，也可以自己照着文档依葫芦画瓢，但是这样弄出的环境是否能达到高可用就难说了。事实上，大部分人所说的HA，还是狭义上的HA，也就是OS一级的双机热备。<br /><br /><strong><font color="#0000ff">RAC</font></strong>是real application cluster的简称，它是在多个主机上运行一个数据库的技术，即是一个db多个instance。它的好处是 可以由多个性能较差的机器构建出一个整体性能很好的集群，并且实现了负载均衡，那么当一个节点出现故障时，其上的服务会自动转到另外的节点去执行，用户甚 至感觉不到什么。<br /><strong><br />双机热备（HA）和RAC有啥区别呢?</strong><br /><br />1、对于硬件来说，基本上一样，共享存储、光纤线（也有还用SCSI线的）、多台小型机（可以做多节点的相互热备，也可以做多节点的RAC）、光纤交换机（如果是用光纤卡的话）；但做RAC，在主机之间，最好使用高带宽网络交换机（虽然不用也可以做成）；因此硬件成本相差不大。<br />2、软件呢，差别可不小。如果是双机热备，必须买操作系统级的双机管理软件；如果是RAC，目前还是建议购买双机管理软件（尽管10g的crs+asm可以摆脱双机软件了，但ASM目前实在太难伺候了），当然还得买RAC license。<br />3、日常维护。RAC要求的技术含量更高，也应该更勤快。最关键的是得买oracle服务，否则遇到有些问题（bug），你就比单机还不高可用了。<br />4、优缺点。这个，看看RAC的官方论述吧。如果能用好，确实是很有好处的。目前我们的40多个客户的使用情况来看，RAC确实大大降低了他们的downtime，另一方面可以说就是提高了生产力咯。<br /><br /><font color="#0000ff"><strong>Dataguard</strong></font>一般是出于容灾的目的。是主数据库的备用库（standby 库）通过自动传送和接受archivelog，并且在dataguard库自动apply 这些log，从而达到和主数据库同步的目的，可能dataguard 库是建立的异地的，当主库所在的区域出现了致命性的灾难时(火灾、地震等)，主库没法修复时，这时可以切换dataguard 为主库的模式，对外提供服务，而它的数据基本是当前最新的。目前可能大家对于 dataguard 库的使用已经拓展出了其他更多的用途，比如备份，跑报表等等。<img src ="http://www.blogjava.net/diggbag/aggbug/361401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2011-10-17 10:08 <a href="http://www.blogjava.net/diggbag/articles/361401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JTDS驱动连接SQLServer异常解决</title><link>http://www.blogjava.net/diggbag/articles/360263.html</link><dc:creator>哲同</dc:creator><author>哲同</author><pubDate>Sun, 09 Oct 2011 05:22:00 GMT</pubDate><guid>http://www.blogjava.net/diggbag/articles/360263.html</guid><wfw:comment>http://www.blogjava.net/diggbag/comments/360263.html</wfw:comment><comments>http://www.blogjava.net/diggbag/articles/360263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/diggbag/comments/commentRss/360263.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/diggbag/services/trackbacks/360263.html</trackback:ping><description><![CDATA[<span lang="EN-US">1.</span>出现的问题<span lang="EN-US"><br />&nbsp; </span>日志文件没有新的输出。<span lang="EN-US"><br /><br />2.</span>问题分析<span lang="EN-US"><br />&nbsp; dump</span>出堆栈，如下：<span lang="EN-US"><br />&nbsp; "main" prio=10 tid=0x000000005de12000 nid=0x27e8 runnable [0x0000000040240000]<br />&nbsp;&nbsp; java.lang.Thread.State: RUNNABLE<br />&nbsp;&nbsp;&nbsp; at java.net.SocketInputStream.socketRead0(Native Method)<br />&nbsp;&nbsp;&nbsp; at java.net.SocketInputStream.read(SocketInputStream.java:129)<br />&nbsp;&nbsp;&nbsp; at java.io.DataInputStream.readFully(DataInputStream.java:178)<br />&nbsp;&nbsp;&nbsp; at java.io.DataInputStream.readFully(DataInputStream.java:152)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:842)<br />&nbsp;&nbsp;&nbsp; </span><span style="color: red" lang="EN-US">at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:723)</span><span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; </span><span style="color: red" lang="EN-US">- locked &lt;0x0000000759fd9f90&gt; (a java.util.ArrayList)</span><span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:135)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.ResponseStream.readString(ResponseStream.java:290)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.ResponseStream.readNonUnicodeString(ResponseStream.java:274)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.TdsData.readData(TdsData.java:936)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.TdsCore.tdsRowToken(TdsCore.java:3007)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2270)<br />&nbsp;&nbsp;&nbsp; at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:765)<br />&nbsp;&nbsp;&nbsp; </span><span style="color: red" lang="EN-US">at net.sourceforge.jtds.jdbc.JtdsResultSet.next(JtdsResultSet.java:596)</span><span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)<br />&nbsp;&nbsp;&nbsp; at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207)<br />&nbsp;&nbsp;&nbsp; at com.jd.cis.worker.OppProductWorker.importData(OppProductWorker.java:310)<br />&nbsp;&nbsp;&nbsp; at com.jd.cis.worker.BaseWorker.importDataSource(BaseWorker.java:416)<br />&nbsp;&nbsp;&nbsp; at com.jd.cis.worker.OppProductWorker.doRun(OppProductWorker.java:276)<br />&nbsp;&nbsp;&nbsp; at com.jd.cis.worker.BaseWorker.run(BaseWorker.java:448)<br />&nbsp;&nbsp;&nbsp; at com.jd.cis.worker.OppProductWorker.main(OppProductWorker.java:564)<br /><br />&nbsp;&nbsp;&nbsp; </span>上面有锁，对应的代码为<span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; statement.setFetchSize(1000);<br />&nbsp;&nbsp;&nbsp; .....<br />&nbsp;&nbsp;&nbsp; resultSet = statement.executeQuery();<br />&nbsp;&nbsp;&nbsp; </span><span style="color: red" lang="EN-US">while (resultSet.next()) {</span><span lang="EN-US"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; </span>查询相关文档，了解到<span lang="EN-US">JTDS</span>默认的<span lang="EN-US">socketTimeout</span>为<span lang="EN-US">0</span>，即读取数据没有超时时间。<span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; </span>当数据链接意外终止的时候，<span lang="EN-US">JDTS</span>可能检测不到，就会一直等待数据，阻塞进程。<span lang="EN-US"><br /><br />&nbsp;&nbsp;&nbsp; </span>在本地重现该问题，在循环体里面设置断点，进入断点后，断掉所有网络链接，取消断点，继续运行，发现程序被一致阻塞了。<span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; </span>当设置<span lang="EN-US">socketTimeout</span>为<span lang="EN-US">60</span>秒，重试，程序阻塞<span lang="EN-US">60</span>秒后抛出异常。<span lang="EN-US"><br /><br />&nbsp;&nbsp;&nbsp; </span>该问题在查询<span lang="EN-US">SQLServer</span>数据库，大数据量查询，分批获取的时候，容易出现<span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; <br />3.</span>解决方案<span lang="EN-US"><br />&nbsp; </span>为<span lang="EN-US">jdts</span>的<span lang="EN-US">url</span>链接中加上<span lang="EN-US">socketTimeout</span>（单位秒）的设置，或在<span lang="EN-US">dbcp</span>中如下设置<span lang="EN-US"><br />&nbsp; &lt;property name="connectionProperties" value="characterEncoding=UTF-8;</span><span style="color: red" lang="EN-US">socketTimeout=60</span><span lang="EN-US">"/&gt;<br />&nbsp; </span>这个参数和<span lang="EN-US">mybatis</span>的<span lang="EN-US">defaultStatementTimeout </span>参数是不一样的<span lang="EN-US"><br /><br />&nbsp; </span>同时<span lang="EN-US">Worker</span>中加入异常捕获重试机制<span lang="EN-US"><br /></span><img src ="http://www.blogjava.net/diggbag/aggbug/360263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/diggbag/" target="_blank">哲同</a> 2011-10-09 13:22 <a href="http://www.blogjava.net/diggbag/articles/360263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>