﻿<?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-走好脚下的路,让别人去说吧!-随笔分类-Java专题-系统架构</title><link>http://www.blogjava.net/human2008/category/28782.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 11 Jan 2008 14:49:20 GMT</lastBuildDate><pubDate>Fri, 11 Jan 2008 14:49:20 GMT</pubDate><ttl>60</ttl><item><title>JavaEE事务扫盲笔记之一扫扫到尾  </title><link>http://www.blogjava.net/human2008/archive/2008/01/11/174503.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Fri, 11 Jan 2008 01:44:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/11/174503.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/174503.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/11/174503.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/174503.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/174503.html</trackback:ping><description><![CDATA[<h2>1.资料</h2>
<ul>
    <li><span class="nobr"><a title="Visit page outside Confluence" href="http://www.infoq.com/minibooks/JTDS" rel="nofollow" mce_href="http://www.infoq.com/minibooks/JTDS" linktype="raw" linktext="《Java Transaction Design Strategies》|http://www.infoq.com/minibooks/JTDS">《Java Transaction Design Strategies》<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" mce_src="http://www.blogjava.net/images/icons/linkext7.gif" /></sup></a></span>&#8201;&nbsp;InfoQ minibook，最好的电子文档，对Java事务处于懵懂状态的必读。
    <li>《Expert One on one J2EE Development Without EJB 中文版》与<span class="nobr"><a title="Visit page outside Confluence" href="http://www.redsaga.com/spring_ref/2.0/html/transaction.html" rel="nofollow" mce_href="http://www.redsaga.com/spring_ref/2.0/html/transaction.html" linktype="raw" linktext="Spring参考手册中文版|http://www.redsaga.com/spring_ref/2.0/html/transaction.html">Spring参考手册中文版<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" mce_src="http://www.blogjava.net/images/icons/linkext7.gif" /></sup></a></span>&#8201; 中的相关章节可以看到spring guys的意见。</li>
</ul>
<h2><a class="" name="Transaction-2.%E6%9C%AC%E5%9C%B0%E4%BA%8B%E5%8A%A1%E4%B8%8E%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1"></a>2.本地事务与分布式事务</h2>
<ul>
    <li><strong>本地事务</strong><br />
    完全依赖于DB、JMS自身，，如直接调用jdbc中的conn.commit();这里没应用服务器什么事，所以也不支持多数据源的全局事务。
    <li><strong>分布式事务</strong><br />
    在JavaEE世界的事务在JTA、JTS规范和XA Sources之上实现。<br />
    JTA是用户编程接口，JTS是服务器底层服务，两者一般由应用服务器自带实现，而<span class="nobr"><a title="Visit page outside Confluence" href="http://www.atomikos.com/" rel="nofollow" mce_href="http://www.atomikos.com/" linktype="raw" linktext="atomikos|http://www.atomikos.com/">atomikos<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" mce_src="http://www.blogjava.net/images/icons/linkext7.gif" /></sup></a></span>&#8201;、<span class="nobr"><a title="Visit page outside Confluence" href="http://jotm.objectweb.org/" rel="nofollow" mce_href="http://jotm.objectweb.org/" linktype="raw" linktext="JOTM|http://jotm.objectweb.org/">JOTM<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" mce_src="http://www.blogjava.net/images/icons/linkext7.gif" /></sup></a></span>&#8201;和<span class="nobr"><a title="Visit page outside Confluence" href="http://labs.jboss.com/jbosstm" rel="nofollow" mce_href="http://labs.jboss.com/jbosstm" linktype="raw" linktext="JBoss Transaction|http://labs.jboss.com/jbosstm">JBoss Transaction<sup><img class="rendericon" height="7" alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" mce_src="http://www.blogjava.net/images/icons/linkext7.gif" /></sup></a></span>&#8201;是专门搞局抢生意的。<br />
    XA Sources其实先于JavaEE而存在，JDBC driver必须有javax.sql.XADataSource接口的实现类，否则所谓二阶段提交就是个伪能力。<br />
    JavaEE除了支持JDBC和JMS外，还引入了JCA模型。JCA可以说是目前唯一可移植的插入JavaEE事务的资源模型，因此像JDO这类框架/Server就是靠乖乖出自己的JCA连接器来参与JavaEE事务的。</li>
</ul>
<h2><a class="" name="Transaction-3.%E7%BC%96%E7%A8%8B%E5%BC%8F%E6%A8%A1%E5%9E%8B"></a>3.编程式模型</h2>
<p>&nbsp;&nbsp;&nbsp; 手工调用jdbc的connection事务方法和使用JTA接口都属于编程式开发，在EJB中叫BMT(Bean管理事务)。<br />
&nbsp;&nbsp;&nbsp; JTA最重要的接口就是UserTransaction和它的六个方法-begin，commit，rollback，getStatus，setRollbackonly，setTransactionTimeout。<br />
&nbsp;&nbsp;&nbsp; 程序需要UserTransaction时可以从JNDI领取，不过JNDI名随应用服务器不同而不同。EJB3里可以直接用个@Resource注入。</p>
<h2><a class="" name="Transaction-4.%E5%AE%A3%E5%91%8A%E5%BC%8F%E6%A8%A1%E5%9E%8B"></a>4.宣告式模型</h2>
<p>&nbsp;&nbsp;&nbsp; 前面都是铺垫，这个才是主打的事务模型，如EJB的CMT(容器管理事务)和Sprin。</p>
<p>&nbsp;&nbsp;&nbsp; 其中EJB2.0，Spring1.0在部署描述符和applicationContext.xml中定义，而EJB3.0和Spring2.0则采用annotation。</p>
<h3><a class="" name="Transaction-4.1%E4%BA%8B%E5%8A%A1%E7%B1%BB%E5%9E%8B"></a>4.1 事务类型</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 这里JavaEE与Spring的定义基本相同：</p>
<ul>
    <li>Required：如果Context中有事务就加入，没有就自己创建一个。(最常用设置)
    <li>Mandatory：永远加入一个事务。如果当前Context没有事务，抛出异常。(那些不打算自己负责rollback事务的方法，必须加入到别人的事务，由别人来控制rollback)
    <li>RequiresNew：永远新建一个事务。(那些不管别人如何，自己必须提交事务的方法，比如审计信息是一定要写的)
    <li>Supports：如果有事务就加入，如果没有就算了。永远不会创建新事务。(一般用于只读方法，不会主动创建事务，但如果当前有事务就加入，以读到事务中未提交的数据)
    <li>NotSupported：永远不使用事务，如果当前有事务，挂起事务。(那些有可能抛异常但异常并不影响全局的方法)
    <li>Never：不能在有当前事务的情况下调用本方法。（生人勿近?)</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可见，Required是默认的设置，Supports是只读方法的最佳选择。</p>
<h3><a class="" name="Transaction-4.2%E4%BA%8B%E5%8A%A1%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB"></a>4.2 事务隔离级别</h3>
<ul>
    <li>ReadUncommited：本事务可以看到另一事务未提交的数据。脏读。
    <li>ReadCommited：本事务只可以看到另一事务已提交的数据。不可重复读。
    <li>RepeatableRead：可重复读。在一个事务内，第一次读到的数据，在本事务没有提交前，无论另一个事务如何提交数据，本事务读到的数据都是不变的。
    <li>Serializable：串行化，同时只有一个事务能读相同的数据。</li>
</ul>
<p>&nbsp;&nbsp;&nbsp; 级别越低越安全效率也越低。隔离级别需要相关资源支持，如重复读在Oracle里会降级为ReadCommited。Spring里默认的Default级别完全看数据源的脸色行事。</p>
<h3><a class="" name="Transaction-4.3%E5%85%B3%E4%BA%8ERollback"></a>4.3 关于Rollback</h3>
<p>&nbsp;&nbsp;&nbsp; EJB里，想rollback只能sessionContext.setRollbackOnly()，或者抛出EJBException。(EJB3还可以annotation设置某些自定义Exception可以触发rollback)</p>
<p>&nbsp;&nbsp;&nbsp; 在Spring里，同样只会rollback unchecked exception(RuntimeExcption及子类)，而checked exception(Exception及子类)是不会rollback的，除非你特别声明。</p>
<div class="macro" macrotext="{code}" command="code">
<div class="code">
<div class="codeContent">
<pre class="code-java">&nbsp;&nbsp;&nbsp;@Transactional(readOnly = <span class="code-keyword">false</span>, propagation = Propagation.REQUIRES_NEW,rollbackFor = {MyException1.class,MyException2.class})</pre>
</div>
</div>
</div>
<p>&#8201;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;因此所有在service层方法中用throws定义的Exception，都必须在事务定义中进行rollback设定。(请勿善忘)</p>
<p>&nbsp;&nbsp;&nbsp; 所有在service层方法中c被atch处理了的异常，又希望容器辅助rollback的话，必须重抛一个预定义的RuntimeException的子类。(请勿回望)</p>
<h3><a class="" name="Transaction-4.4%E5%85%B3%E4%BA%8ESpring"></a>4.4 关于Spring</h3>
<p>&nbsp;&nbsp;&nbsp; Spring不希望编程式事务管理。<br />
&nbsp;&nbsp;&nbsp; Spring也不希望使用EJB CMT--CMT依赖于EJB而无法用于POJO，依赖于JTA全局事务对单数据源场景造成了浪费，而且rollback机制比较麻烦（必须为EJBException或手工setRollbackOnly())。<br />
&nbsp;&nbsp;&nbsp; 因此Spring通过AOP实现了对POJO的整套宣告式事务体系；对jdbc,hibernate,jpa,jms等local数据源和JTA实现了统一的事务管理机制，而且支持本地资源与JTA在配置文件级的切换，而且改进了rollback机制。</p>
<p>&nbsp;&nbsp; 1）一个本地事务管理器：</p>
<div class="macro" macrotext="{code}" command="code">
<div class="code">
<div class="codeContent">
<pre class="code-java">&lt;bean id=<span class="code-quote">"transactionManager"</span>&nbsp;&nbsp;class=<span class="code-quote">"org.springframework.orm.jpa.JpaTransactionManager"</span>&gt;&nbsp;&nbsp;&lt;property name=<span class="code-quote">"entityManagerFactory"</span> ref=<span class="code-quote">"entityManagerFactory"</span> /&gt;&nbsp;&lt;/bean&gt;</pre>
</div>
</div>
</div>
<p>&#8201;</p>
<p>&nbsp;&nbsp; 2）Spring就会把请求都转发到应用服务器的JTA对象上（注意此时数据源也需要改为用JNDI从应用服务器获取)。</p>
<div class="macro" macrotext="{code}" command="code">
<div class="code">
<div class="codeContent">
<pre class="code-java">&lt;bean id=<span class="code-quote">"myTxManager"</span> class=<span class="code-quote">"org.springframework.transaction.jta.JtaTransactionManager"</span>/&gt;</pre>
</div>
</div>
</div>
<p>&#8201;</p>
<p>&nbsp;&nbsp; 3）应用服务器专有的类型的JTA事务管理器：</p>
<div class="macro" macrotext="{code}" command="code">
<div class="code">
<div class="codeContent">
<pre class="code-java">&lt;bean id=<span class="code-quote">"myTxManager"</span> class=<span class="code-quote">"org.springframework.transaction.jta.WebLogicJtaTransactionManager"</span>/&gt;</pre>
</div>
</div>
</div>
<p>&#8201;</p>
<img src ="http://www.blogjava.net/human2008/aggbug/174503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-11 09:44 <a href="http://www.blogjava.net/human2008/archive/2008/01/11/174503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可以开始用Struts2.0了</title><link>http://www.blogjava.net/human2008/archive/2008/01/08/173776.html</link><dc:creator>灵!</dc:creator><author>灵!</author><pubDate>Tue, 08 Jan 2008 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/human2008/archive/2008/01/08/173776.html</guid><wfw:comment>http://www.blogjava.net/human2008/comments/173776.html</wfw:comment><comments>http://www.blogjava.net/human2008/archive/2008/01/08/173776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/human2008/comments/commentRss/173776.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/human2008/services/trackbacks/173776.html</trackback:ping><description><![CDATA[Apache已经发布了Struts2.0的正式版，即2.0.6GA版本。这个版本已经可以在项目中正式使用了。当然大家一定很关心，从webwork2.2迁移到struts2.0麻烦不麻烦，请看Struts2.0的FAQ： <br />
<br />
<div class="quote_title">引用</div>
<div class="quote_div">Essentially, Struts 2.0 is the technical equivalent of WebWork 2.3. Aside from the package and property renaming, it isn't much different than, say, migrating from WebWork 2.1 to 2.2.</div>
<br />
<br />
Struts2.0其实就是webwork2.3而已，从webwork2.2迁移到struts2.0不会比从webwork2.1到2.2更麻烦。 <br />
<br />
webwork2.2和struts2.0差异对比： <br />
http://struts.apache.org/2.x/docs/key-changes-from-webwork-2.html <br />
<br />
迁移步骤： <br />
http://struts.apache.org/2.x/docs/webwork-2-migration-strategies.html <br />
<br />
总结： <br />
<br />
大致来说，struts2.0就是把package和配置文件的名字改了改而已，别的没有做什么改动，所以现在用struts2.0和用webwork2.2没有多大区别。当然这迁移一迁就是将近两年，还是有点进步的： <br />
<br />
1、搭配struts2.0的xwork版本必须使用xwork2.0.1，而xwork2.0.1集成了可选的Google Guice IoC容器 <br />
2、Struts2.0弄了一个plugin机制，来适配各种扩展机制 <br />
3、全面引入annotation语法，验证，拦截都可以用annotation了。 <br />
<br />
所以用webwork的同志们，大胆的迁移到struts2.0来吧。 
<img src ="http://www.blogjava.net/human2008/aggbug/173776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/human2008/" target="_blank">灵!</a> 2008-01-08 20:21 <a href="http://www.blogjava.net/human2008/archive/2008/01/08/173776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>