﻿<?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-清睛仪明-文章分类-Spring</title><link>http://www.blogjava.net/msmary/category/26452.html</link><description>书山有路勤为径，学海无涯苦作舟</description><language>zh-cn</language><lastBuildDate>Thu, 25 Oct 2007 17:49:47 GMT</lastBuildDate><pubDate>Thu, 25 Oct 2007 17:49:47 GMT</pubDate><ttl>60</ttl><item><title>Spring in Action 学习笔记—第七章 访问企业服务</title><link>http://www.blogjava.net/msmary/articles/155407.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:52:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155407.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155407.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155407.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155407.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本章向读者展示了在Spring中如何集成其他企业服务，读者将了解到使用Spring集成邮件服务、JMS甚至EJB都是那么的容易。Spring并没有对一些企业服务提供直接的支持。它依赖其他API来提供有关服务，但对这些服务通过相应的抽象层进行了封装，因此使用起来更为方便。一、从JNDI中获取对象JNDI为Java应用程序提供了一个用于存储应用对象的中心仓库。Spring的JNDI抽象...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155407.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:52 <a href="http://www.blogjava.net/msmary/articles/155407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action 学习笔记—第六章 远程调用</title><link>http://www.blogjava.net/msmary/articles/155405.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155405.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155405.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155405.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155405.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 远程调用是客户端应用和服务端之间的会话。在客户端上所需要的一些功能并不包括在该应用的职能范围内。所以应用向能提供这些功能的其他系统寻求帮助。远程的应用通过远程服务把这些功能公开出来。&nbsp;一、Spring远程调用概览Spring为各种远程访问技术的集成提供了工具类。Spring远程支持是由普通（Spring）POJO实现的，这使得开发具有远程访问功能的服务变得相当容易。Spr...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155405.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:51 <a href="http://www.blogjava.net/msmary/articles/155405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action 学习笔记—第四章 征服数据库(转)</title><link>http://www.blogjava.net/msmary/articles/155403.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:47:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155403.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155403.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155403.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155403.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155403.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 先是一个好消息，在2006年国庆期间，Spring2.0正式版（http://www.springframework.org/download）和Spring2.0中文文档（http://spring.jactiongroup.net/viewtopic.php?t=2279&amp;sid=0906ae6a913537b249e501db5b54c181）终于发布了。在前面的学习之后，我们已...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155403.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:47 <a href="http://www.blogjava.net/msmary/articles/155403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action 学习笔记—第三章创建切面(转)</title><link>http://www.blogjava.net/msmary/articles/155402.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:44:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155402.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155402.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155402.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155402.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring的AOP（Aspect Oriented Programming）框架允许你将分散在系统中的功能放到一个地方—切面。依赖Spring的强大切入点机制，何时何地在系统中采用切面你有很多种选择。在本章中作者向我们介绍并且展示了Spring AOP基础的方方面面。一、AOP介绍AOP提供了另外一种思考程序结构的角度，弥补了OOP（面向对象编程）的不足。大家可以参看夏昕编写的《Spri...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155402.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:44 <a href="http://www.blogjava.net/msmary/articles/155402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action 学习笔记—第二章 装配Bean(转)</title><link>http://www.blogjava.net/msmary/articles/155401.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:43:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155401.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155401.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155401.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在本章中作者讲解了Spring的IoC概念，详细介绍了如何配置我们自己的应用系统，如何编写松耦合的组件。如何在XML中配置Bena。这里提个建议，现在的Spring已经升级到2.0版本了，而本书（《Spring in Action》）出版时还是Spring1.X。2.0有了较大的变化建议新学Spring的人下载2.0版本的来学习，现在最新的版本已经是Rc3了。同时2.0版本的中文参考已经在Sp...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155401.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:43 <a href="http://www.blogjava.net/msmary/articles/155401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action学习笔记--楔子(转)</title><link>http://www.blogjava.net/msmary/articles/155399.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155399.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155399.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155399.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155399.html</trackback:ping><description><![CDATA[<p style="margin: 7.8pt 0cm 0pt; line-height: 15pt"><strong><span style="font-size: 14pt; color: #3366ff; font-family: 宋体">一、起因</span></strong></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">我是一个</span><span style="font-size: 12pt"><font face="Times New Roman">Java</font></span><span style="font-size: 12pt; font-family: 宋体">程序员，</span><span style="font-size: 12pt"><font face="Times New Roman">Java</font></span><span style="font-size: 12pt; font-family: 宋体">写的多了，自然而然想往</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">（现在叫</span><span style="font-size: 12pt"><font face="Times New Roman">JavaEE</font></span><span style="font-size: 12pt; font-family: 宋体">了）方面发展。于是我开始翻看</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">方面的资料，在网上查，在论坛问。最后我查到一大堆词，像什么</span><span style="font-size: 12pt"><font face="Times New Roman">Struts</font></span><span style="font-size: 12pt; font-family: 宋体">、</span><span style="font-size: 12pt"><font face="Times New Roman">Webwork</font></span><span style="font-size: 12pt; font-family: 宋体">、</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">、</span><span style="font-size: 12pt"><font face="Times New Roman">Hibernate</font></span><span style="font-size: 12pt; font-family: 宋体">、</span><span style="font-size: 12pt"><font face="Times New Roman">EJB</font></span><span style="font-size: 12pt; font-family: 宋体">等等，这些能叫上名字的都是牌子大的，更有不计其数的我叫不上来名字或者根本就没有听说过的。于是我大概每个都看看。看的最多的是</span><span style="font-size: 12pt"><font face="Times New Roman">Struts</font></span><span style="font-size: 12pt; font-family: 宋体">，当我看到略为深入的部分后，各种各样的设计模式一股脑儿的全都冒了出来。于是我开始学习设计模式，起初我本来想碰到一个模式学一个。但是看着看着，好多模式在一起混用，于是我不得不停下来花好多时间来学习。最后下了个决心干脆把模式全部来一遍算了。所以有了我的设计模式一些列文章。（关于设计模式的文章请看：</span><span style="font-size: 12pt"><a href="http://blog.csdn.net/qutr/category/125050.aspx"><font face="Times New Roman">http://blog.csdn.net/qutr/category/125050.aspx</font></a></span><span style="font-size: 12pt; font-family: 宋体">和</span><span style="font-size: 12pt"><a href="http://blog.csdn.net/qutr/category/166495.aspx"><font face="Times New Roman">http://blog.csdn.net/qutr/category/166495.aspx</font></a></span><span style="font-size: 12pt; font-family: 宋体">）</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">在设计模式看完以后，我忙了一段时间，</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">的学习也就停了下来。之后我又将</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">的学习提上了学习日程。但是现在我有些迷茫了，这么一大堆名词他们和</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">到底是什么关系，他们之间到底有什么样的联系以及用哪个好，不用哪个好？这些问题让我十分的烦恼。</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">直到最后我读了</span><font size="3"><strong><font face="Times New Roman">Rod Johnson</font></strong><span style="font-family: 宋体">（关于</span><font face="Times New Roman">Rod</font><span style="font-family: 宋体">我就不说了</span><font face="Times New Roman">Spring</font><span style="font-family: 宋体">的创始人，但网上有人这样评价他：&#8220;我对</span><font face="Times New Roman">Rod</font><span style="font-family: 宋体">的敬佩不是因为他发明了</span><font face="Times New Roman">Spring</font><span style="font-family: 宋体">，而是他对</span><font face="Times New Roman">J2EE</font><span style="font-family: 宋体">开发的深刻理解&#8221;）</span><span style="font-size: 12pt; font-family: 宋体">的文章<strong>《</strong></span><strong><span style="font-size: 12pt"><font face="Times New Roman">Introduce To Spring Framework</font></span></strong><strong><span style="font-size: 12pt; font-family: 宋体">》</span></strong><span style="font-size: 12pt; font-family: 宋体">（<span style="color: #3366ff">英文原文：</span></span><span style="font-size: 12pt; color: #3366ff"><a href="http://www.theserverside.com/tt/articles/article.tss?l=SpringFramework"><span style="color: #3366ff"><font face="Times New Roman">http://www.theserverside.com/tt/articles/article.tss?l=SpringFramework</font></span></a></span><span style="font-size: 12pt; color: #3366ff; font-family: 宋体">；中文翻译：</span><span style="font-size: 12pt; color: #3366ff"><font face="Times New Roman">http://forum.javaeye.com/viewtopic.php?t=4919</font></span><span style="font-size: 12pt; font-family: 宋体">）后我才渐渐明白了一些概念，</span><strong><font face="Times New Roman">Rod</font></strong><span style="font-size: 12pt; font-family: 宋体">的这篇文章相当精彩，从头到尾讲解了</span></font><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">的功能，讲解了</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">的各个模块的实现意图。得到的结论是：</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">是个小而全的轻量级</span><strong><span style="font-size: 12pt"><font face="Times New Roman">J2EE Framework</font></span></strong><span style="font-size: 12pt; font-family: 宋体">。原来论坛上和网上大家说的</span><span style="font-size: 12pt"><font face="Times New Roman">Struts</font></span><span style="font-size: 12pt; font-family: 宋体">（</span><span style="font-size: 12pt"><font face="Times New Roman">Webwork</font></span><span style="font-size: 12pt; font-family: 宋体">）</span><span style="font-size: 12pt"><font face="Times New Roman">+Spring+Hibernate</font></span><span style="font-size: 12pt; font-family: 宋体">是利用了</span><span style="font-size: 12pt"><font face="Times New Roman">Struts</font></span><span style="font-size: 12pt; font-family: 宋体">（</span><span style="font-size: 12pt"><font face="Times New Roman">Webwork</font></span><span style="font-size: 12pt; font-family: 宋体">）的</span><span style="font-size: 12pt"><font face="Times New Roman">MVC</font></span><span style="font-size: 12pt; font-family: 宋体">功能，</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">的</span><span style="font-size: 12pt"><font face="Times New Roman">Ioc</font></span><span style="font-size: 12pt; font-family: 宋体">和</span><span style="font-size: 12pt"><font face="Times New Roman">Aop</font></span><span style="font-size: 12pt; font-family: 宋体">功能还有</span><span style="font-size: 12pt"><font face="Times New Roman">Hibernate</font></span><span style="font-size: 12pt; font-family: 宋体">的数据库操作功能。至此我决定以</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">为切入点来学习</span><span style="font-size: 12pt"><font face="Times New Roman">J2EE</font></span><span style="font-size: 12pt; font-family: 宋体">技术。</span></p>
<p style="margin: 7.8pt 0cm 0pt; line-height: 20pt"><strong><span style="font-size: 14pt; color: #3366ff; font-family: 宋体">二、关于《</span></strong><strong><span style="font-size: 14pt; color: #3366ff"><font face="Times New Roman">Spring In Action</font></span></strong><strong><span style="font-size: 14pt; color: #3366ff; font-family: 宋体">》</span></strong></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">我觉得写这本书的两位作者真是两个牛人，不仅对</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">理解的好，而且似乎懂得心理学的知识。他们抓住了读者的心理，将一些基本概念讲解的比较清楚，而且对一些名词如</span><span style="font-size: 12pt"><font face="Times New Roman">Struts</font></span><span style="font-size: 12pt; font-family: 宋体">，</span><span style="font-size: 12pt"><font face="Times New Roman">Webwork</font></span><span style="font-size: 12pt; font-family: 宋体">等作了简短的解释和与</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">的比较。诠释了学习者心中的疑惑，自然这本书深深的吸引了我。</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">在书买回来的前几天里我看得非常快，开始看得很过瘾，渐渐的越看越迷糊，越看约看不懂了。最后我发现原因就是：光看不练造成的。于是我下定决心：不做草上飞，踏踏实实向前进。</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">为什么要写学习笔记？我觉得这是督促强迫我坚持学习的唯一途径（我这个人比较懒</span><span style="font-size: 12pt; font-family: Wingdings">J</span><span style="font-size: 12pt; font-family: 宋体">）。</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">整本书的学习笔记我会以章为单位，每次在</span><span style="font-size: 12pt"><font face="Times New Roman">Blog</font></span><span style="font-size: 12pt; font-family: 宋体">上发布一章的内容。有些章的内容可能太多或者对我来说太难我会好长时间才把学习笔记写出来；有些章的内容可能对我来说暂时没什么用处，我可能会不写或者非常简单的摘录。网上好多人反映出版社和作者不负责任没有将书中的源代码呈现给读者。我想这是坏事，但是反过来也是好事。没有完整的源代码我们正好可以自己写出来，那样更会加深对</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">知识的理解。在整个的学习过程中我会试着把作者所说的知识点和各模块，各个类的代码完整的写出来贴到文章中，还会做一些详细的解释。有些实在重复的内容，我只列出代码片段，做一些解释。</span></p>
<p style="margin: 7.8pt 0cm 0pt; line-height: 20pt"><strong><span style="font-size: 14pt; color: #3366ff; font-family: 宋体">三、小结</span></strong></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">对该书的整个学习过程我不会就光看这一本书，我会参考其它一些书或文章。这些书是：</span></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体">《精通</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">》</span><span style="font-size: 12pt"><font face="Times New Roman"> by</font></span><span style="font-size: 12pt; font-family: 宋体">罗时飞</span></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体">《</span><span style="font-size: 12pt"><font face="Times New Roman">Spring</font></span><span style="font-size: 12pt; font-family: 宋体">开发指南》</span><span style="font-size: 12pt"><font face="Times New Roman"> by </font></span><span style="font-size: 12pt; font-family: 宋体">夏昕</span></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体">《</span><span style="font-size: 12pt"><font face="Times New Roman">Spring live</font></span><span style="font-size: 12pt; font-family: 宋体">中文版》</span><span style="font-size: 12pt; font-family: 宋体">翻译</span><span style="font-size: 12pt; font-family: 宋体">白汉奇</span></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; font-family: 宋体">《</span><span style="font-size: 12pt"><font face="Times New Roman">Introduce To Spring Framework</font></span><span style="font-size: 12pt; font-family: 宋体">》</span><font face="Times New Roman"><span style="font-size: 12pt">by </span><font size="3"><strong>Rod Johnson</strong></font></font></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><font size="3"><span style="font-family: 宋体">《</span><font face="Times New Roman">Pro Spring</font><span style="font-family: 宋体">》</span><font face="Times New Roman">(</font><span style="font-family: 宋体">这本书已经有中文版了，好像不错应该好好看看</span><font face="Times New Roman">)</font></font></p>
<p style="margin: 7.8pt 0cm 0pt 45pt; text-indent: -21pt; line-height: 20pt; tab-stops: list 45.0pt"><span style="font-size: 12pt; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><font size="3"><span style="font-family: 宋体">还有其它一些书籍、文章。</span></font></p>
<p style="margin: 7.8pt 0cm 0pt 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">当引用了哪本书或者哪篇文章的段落我会明确表明出处，我的文章是为了自我学习和与大家交流的，没有用于商业用途，所以希望大家也就不要和我纠缠版权了</span><span style="font-size: 12pt; font-family: Wingdings">J</span><span style="font-size: 12pt; font-family: 宋体">。同样引用我文章的个人或网站，希望你们注明出处。</span></p>
<p style="margin: 7.8pt 0cm 0pt; text-indent: 24pt; line-height: 20pt"><span style="font-size: 12pt; font-family: 宋体">最后说一点，我写《</span><span style="font-size: 12pt"><font face="Times New Roman">Spring in Action</font></span><span style="font-size: 12pt; font-family: 宋体">》读书笔记不是为了吸引眼球，而是为了督促自己，将文章发表到</span><span style="font-size: 12pt"><font face="Times New Roman">Blog</font></span><span style="font-size: 12pt; font-family: 宋体">上是为了和大家交流，希望高手看到多多指点。</span></p>
<img src ="http://www.blogjava.net/msmary/aggbug/155399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:41 <a href="http://www.blogjava.net/msmary/articles/155399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring in Action 学习笔记—第五章 事务管理</title><link>http://www.blogjava.net/msmary/articles/155398.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:33:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155398.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155398.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155398.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155398.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本章是第四章的延续，作者向读者展示了如何使用Spring事务管理来保证数据一致性。Spring对事务的管理有丰富的支持，程序控制的和声明式的都有。在本章中，我们会学习到如何把应用程序的代码放置在事务中，以确保在一切顺利时，所有的成果都被固定下来；一旦其中有一步出错，那么整个事情就像没有发生一样。&nbsp;一、理解事务首先我们应该弄清楚什么是事务，这样才能认识到事务的重要性。举一个小小...&nbsp;&nbsp;<a href='http://www.blogjava.net/msmary/articles/155398.html'>阅读全文</a><img src ="http://www.blogjava.net/msmary/aggbug/155398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:33 <a href="http://www.blogjava.net/msmary/articles/155398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务传播机制解惑</title><link>http://www.blogjava.net/msmary/articles/155395.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Tue, 23 Oct 2007 13:26:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/155395.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/155395.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/155395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/155395.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/155395.html</trackback:ping><description><![CDATA[&nbsp;
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">概述</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">当我们调用一个基于</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">的</span><span style="color: #323432; font-family: Verdana">Service</span><span style="color: #323432; font-family: 宋体">接口方法（如</span><span style="color: #323432; font-family: Verdana">UserService#addUser()</span><span style="color: #323432; font-family: 宋体">）时，它将运行于</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">管理的事务环境中，</span><span style="color: #323432; font-family: Verdana">Service</span><span style="color: #323432; font-family: 宋体">接口方法可能会在内部调用其它的</span><span style="color: #323432; font-family: Verdana">Service</span><span style="color: #323432; font-family: 宋体">接口方法以共同完成一个完整的业务操作，因此就会产生服务接口方法嵌套调用的情况，</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">通过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">事务传播是</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">进行事务管理的重要概念，其重要性怎么强调都不为过。但是事务传播行为也是被误解最多的地方，在本文里，我们将详细分析不同事务传播行为的表现形式，掌握它们之间的区别。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">事务传播行为种类</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">在</span><span style="color: #323432; font-family: Verdana">TransactionDefinition</span><span style="color: #323432; font-family: 宋体">接口中规定了</span><span style="color: #323432; font-family: Verdana">7</span><span style="color: #323432; font-family: 宋体">种类型的事务传播行为，它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播：</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><a name="_Ref160706115"><span style="color: black; font-family: 宋体">表</span></a><span style="color: #323432; font-family: Verdana">1</span><span style="color: #323432; font-family: 宋体">事务传播行为类型</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: #cccccc 1pt inset; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" width="201">
            <p style="line-height: 16.5pt; text-align: center" align="center"><span style="color: #323432; font-family: 宋体">事务传播行为类型</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: #cccccc 1pt inset; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" width="358">
            <p style="line-height: 16.5pt; text-align: center" align="center"><span style="color: #323432; font-family: 宋体">说明</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">如果当前没有事务，就新建一个事务，如果已经存在一个事务中，加入到这个事务中。这是最常见的选择。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_SUPPORTS</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">支持当前事务，如果当前没有事务，就以非事务方式执行。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_MANDATORY</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">使用当前的事务，如果当前没有事务，就抛出异常。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRES_NEW</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">新建事务，如果当前存在事务，把当前事务挂起。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_NOT_SUPPORTED</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_NEVER</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">以非事务方式执行，如果当前存在事务，则抛出异常。</span></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #cccccc 1pt inset; width: 150.75pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="201">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_NESTED</span></p>
            </td>
            <td style="border-right: #cccccc 1pt inset; padding-right: 0.75pt; border-top: medium none; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: medium none; width: 268.5pt; padding-top: 0.75pt; border-bottom: #cccccc 1pt inset" valign="top" width="358">
            <p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">如果当前存在事务，则在嵌套事务内执行。如果当前没有事务，则执行与</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">类似的操作。</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">当使用</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NESTED</span><span style="color: #323432; font-family: 宋体">时，底层的数据源必须基于</span><span style="color: #323432; font-family: Verdana">JDBC 3.0</span><span style="color: #323432; font-family: 宋体">，并且实现者需要支持保存点事务机制。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">几种容易引起误解的组合事务传播行为</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">当服务接口方法分别使用表</span><span style="color: #323432; font-family: Verdana">1</span><span style="color: #323432; font-family: 宋体">中不同的事务传播行为，且这些接口方法又发生相互调用的情况下，大部分组合都是一目了然，容易理解的。但是，也存在一些容易引起误解的组合事务传播方式。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">下面，我们通过两个具体的服务接口的组合调用行为来破解这一难点。这两个服务接口分别是</span><span style="color: #323432; font-family: Verdana">UserService</span><span style="color: #323432; font-family: 宋体">和</span><span style="color: #323432; font-family: Verdana">ForumService</span><span style="color: #323432; font-family: 宋体">，</span><span style="color: #323432; font-family: Verdana">UserSerice</span><span style="color: #323432; font-family: 宋体">有一个</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">方法，</span><span style="color: #323432; font-family: Verdana">ForumSerivce#addTopic()</span><span style="color: #323432; font-family: 宋体">方法调用了</span><span style="color: #323432; font-family: Verdana">UserSerice#addCredits()</span><span style="color: #323432; font-family: 宋体">方法，发生关联性服务方法的调用：</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">public class ForumService {</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">private UserService userService;</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">public void </span><strong><span style="color: #323432; font-family: Verdana">addTopic()</span></strong><span style="color: #323432; font-family: Verdana">{</span><strong><span style="color: #323432; font-family: 宋体">①</span></strong><strong><span style="color: #323432; font-family: 宋体">调用其它服务接口的方法</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">//add Topic&#8230;</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">userService.</span><strong><span style="color: #323432; font-family: Verdana">addCredits()</span></strong><span style="color: #323432; font-family: Verdana">;</span><strong><span style="color: #323432; font-family: 宋体">②</span></strong><strong><span style="color: #323432; font-family: 宋体">被关联调用的业务方法</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">}</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">}</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">嵌套调用的事务方法</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">对</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">事务传播行为最常见的一个误解是：当服务接口方法发生嵌套调用时，被调用的服务方法只能声明为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NESTED</span><span style="color: #323432; font-family: 宋体">。这种观点犯了望文生义的错误，误认为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NESTED</span><span style="color: #323432; font-family: 宋体">是专为方法嵌套准备的。这种误解遗害不浅，执有这种误解的开发者错误地认为：应尽量不让</span><span style="color: #323432; font-family: Verdana">Service</span><span style="color: #323432; font-family: 宋体">类的业务方法发生相互的调用，</span><span style="color: #323432; font-family: Verdana">Service</span><span style="color: #323432; font-family: 宋体">类只能调用</span><span style="color: #323432; font-family: Verdana">DAO</span><span style="color: #323432; font-family: 宋体">层的</span><span style="color: #323432; font-family: Verdana">DAO</span><span style="color: #323432; font-family: 宋体">类，以避免产生嵌套事务。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">其实，这种顾虑是完全没有必要的，</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">已经清楚地告诉我们：事务的方法会足够</span><span style="color: #323432; font-family: Verdana">&#8220;</span><span style="color: #323432; font-family: 宋体">聪明</span><span style="color: #323432; font-family: Verdana">&#8221;</span><span style="color: #323432; font-family: 宋体">地判断上下文是否已经存在一个事务中，如果已经存在，就加入到这个事务中，否则创建一个新的事务。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">依照上面的例子，假设我们将</span><span style="color: #323432; font-family: Verdana">ForumService#addTopic()</span><span style="color: #323432; font-family: 宋体">和</span><span style="color: #323432; font-family: Verdana">UserSerice#addCredits()</span><span style="color: #323432; font-family: 宋体">方法的事务传播行为都设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">，这两个方法将运行于同一个事务中。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">为了清楚地说明这点，可以将</span><span style="color: #323432; font-family: Verdana">Log4J</span><span style="color: #323432; font-family: 宋体">的日志设置为</span><span style="color: #323432; font-family: Verdana">DEBUG</span><span style="color: #323432; font-family: 宋体">级别，以观察</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">事务管理器内部的运行情况。下面将两个业务方法都设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">，</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">所输出的日志信息如下：</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Using transaction object </span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">[org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@e3849c]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">①</span></strong><strong><span style="color: #323432; font-family: 宋体">为</span></strong><strong><span style="color: #323432; font-family: Verdana">ForumService#addTopic()</span></strong><strong><span style="color: #323432; font-family: 宋体">新建一个事务</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: Verdana">Creating new transaction with name [com.baobaotao.service.ForumService.addTopic]:</span></strong><span style="color: #323432; font-family: Verdana"> PROPAGATION_REQUIRED,ISOLATION_DEFAULT</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Acquired Connection [org.apache.commons.dbcp.PoolableConnection@dc41c5] for JDBC transaction</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Switching JDBC Connection [org.apache.commons.dbcp.PoolableConnection@dc41c5] to manual commit</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Bound value [org.springframework.jdbc.datasource.ConnectionHolder@ee1ede] for key [org.apache.commons.dbcp.BasicDataSource@4204] to thread [main]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Initializing transaction synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Getting transaction for [com.baobaotao.service.ForumService.addTopic]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@ee1ede] for key [org.apache.commons.dbcp.BasicDataSource@4204] bound to thread [main]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Using transaction object [org.springframework.jdbc.datasource.DataSourceTransactionManager$DataSourceTransactionObject@8b8a47]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">②</span></strong><strong><span style="color: #323432; font-family: Verdana">UserService#addCredits()</span></strong><strong><span style="color: #323432; font-family: 宋体">简单地加入到已存在的事务中（即</span></strong><strong><span style="color: #323432; font-family: 宋体">①</span></strong><strong><span style="color: #323432; font-family: 宋体">处创建的事务）</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: Verdana">Participating in existing transaction</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Getting transaction for [com.baobaotao.service.UserService.addCredits]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Completing transaction for [com.baobaotao.service.UserService.addCredits]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Completing transaction for [com.baobaotao.service.ForumService.addTopic]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Triggering beforeCommit synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Triggering beforeCompletion synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Initiating transaction commit</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">③</span></strong><strong><span style="color: #323432; font-family: 宋体">调用底层</span></strong><strong><span style="color: #323432; font-family: Verdana">Connection#commit()</span></strong><strong><span style="color: #323432; font-family: 宋体">方法提交事务</span></strong></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Committing JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@dc41c5]</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Triggering afterCommit synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Triggering afterCompletion synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">Clearing transaction synchronization</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">嵌套事务</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">将</span><span style="color: #323432; font-family: Verdana">ForumService#addTopic()</span><span style="color: #323432; font-family: 宋体">设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">时，</span><span style="color: #323432; font-family: Verdana">UserSerice#addCredits()</span><span style="color: #323432; font-family: 宋体">设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">、</span><span style="color: #323432; font-family: Verdana">PROPAGATION_SUPPORTS</span><span style="color: #323432; font-family: 宋体">、</span><span style="color: #323432; font-family: Verdana">PROPAGATION_MANDATORY</span><span style="color: #323432; font-family: 宋体">时，运行的效果都是一致的（当然，如果单独调用</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">就另当别论了）。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">当</span><span style="color: #323432; font-family: Verdana">addTopic()</span><span style="color: #323432; font-family: 宋体">运行在一个事务下（如设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRED</span><span style="color: #323432; font-family: 宋体">），而</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NESTED</span><span style="color: #323432; font-family: 宋体">时，如果底层数据源支持保存点，</span><span style="color: #323432; font-family: Verdana">Spring</span><span style="color: #323432; font-family: 宋体">将为内部的</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">方法产生的一个内嵌的事务。如果</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">对应的内嵌事务执行失败，事务将回滚到</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">方法执行前的点，并不会将整个事务回滚。内嵌事务是内层事务的一部分，所以只有外层事务提交时，嵌套事务才能一并提交。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">嵌套事务不能够提交，它必须通过外层事务来完成提交的动作，外层事务的回滚也会造成内部事务的回滚。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">嵌套事务和新事务</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRES_NEW </span><span style="color: #323432; font-family: 宋体">和</span><span style="color: #323432; font-family: Verdana"> PROPAGATION_NESTED</span><span style="color: #323432; font-family: 宋体">也是容易混淆的两个传播行为。</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRES_NEW </span><span style="color: #323432; font-family: 宋体">启动一个新的、和外层事务无关的</span><span style="color: #323432; font-family: Verdana">&#8220;</span><span style="color: #323432; font-family: 宋体">内部</span><span style="color: #323432; font-family: Verdana">&#8221;</span><span style="color: #323432; font-family: 宋体">事务。该事务拥有自己的独立隔离级别和锁，不依赖于外部事务，独立地提交和回滚。当内部事务开始执行时，外部事务将被挂起，内务事务结束时，外部事务才继续执行。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">由此可见，</span><span style="color: #323432; font-family: Verdana"> PROPAGATION_REQUIRES_NEW </span><span style="color: #323432; font-family: 宋体">和</span><span style="color: #323432; font-family: Verdana"> PROPAGATION_NESTED </span><span style="color: #323432; font-family: 宋体">的最大区别在于：</span><span style="color: #323432; font-family: Verdana">PROPAGATION_REQUIRES_NEW </span><span style="color: #323432; font-family: 宋体">将创建一个全新的事务，它和外层事务没有任何关系，而</span><span style="color: #323432; font-family: Verdana"> PROPAGATION_NESTED </span><span style="color: #323432; font-family: 宋体">将创建一个依赖于外层事务的子事务，当外层事务提交或回滚时，子事务也会连带提交和回滚。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">其它需要注意问题</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: 宋体">以下几个问题值得注意：</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">1) </span><span style="color: #323432; font-family: 宋体">当业务方法被设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_MANDATORY</span><span style="color: #323432; font-family: 宋体">时，它就不能被非事务的业务方法调用。如将</span><span style="color: #323432; font-family: Verdana">ForumService#addTopic()</span><span style="color: #323432; font-family: 宋体">设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_MANDATORY</span><span style="color: #323432; font-family: 宋体">，如果展现层的</span><span style="color: #323432; font-family: Verdana">Action</span><span style="color: #323432; font-family: 宋体">直接调用</span><span style="color: #323432; font-family: Verdana">addTopic()</span><span style="color: #323432; font-family: 宋体">方法，将引发一个异常。正确的情况是：</span><span style="color: #323432; font-family: Verdana">addTopic()</span><span style="color: #323432; font-family: 宋体">方法必须被另一个带事务的业务方法调用（如</span><span style="color: #323432; font-family: Verdana">ForumService#otherMethod()</span><span style="color: #323432; font-family: 宋体">）。所以</span><span style="color: #323432; font-family: Verdana">PROPAGATION_MANDATORY</span><span style="color: #323432; font-family: 宋体">的方法一般都是被其它业务方法间接调用的。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">2) </span><span style="color: #323432; font-family: 宋体">当业务方法被设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NEVER</span><span style="color: #323432; font-family: 宋体">时，它将不能被拥有事务的其它业务方法调用。假设</span><span style="color: #323432; font-family: Verdana">UserService#addCredits()</span><span style="color: #323432; font-family: 宋体">设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NEVER</span><span style="color: #323432; font-family: 宋体">，当</span><span style="color: #323432; font-family: Verdana">ForumService# addTopic()</span><span style="color: #323432; font-family: 宋体">拥有一个事务时，</span><span style="color: #323432; font-family: Verdana">addCredits()</span><span style="color: #323432; font-family: 宋体">方法将抛出异常。所以</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NEVER</span><span style="color: #323432; font-family: 宋体">方法一般是被直接调用的。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><span style="color: #323432; font-family: Verdana">3)</span><span style="color: #323432; font-family: 宋体">当方法被设置为</span><span style="color: #323432; font-family: Verdana">PROPAGATION_NOT_SUPPORTED</span><span style="color: #323432; font-family: 宋体">时，外层业务方法的事务会被挂起，当内部方法运行完成后，外层方法的事务重新运行。如果外层方法没有事务，直接运行，不需要做任何其它的事。</span></p>
<p style="line-height: 16.5pt; text-align: left" align="left"><strong><span style="color: #323432; font-family: 宋体">小结</span></strong></p>
<span style="font-size: 10.5pt; color: #323432; font-family: 宋体">在</span><span style="font-size: 10.5pt; color: #323432; font-family: Verdana">Spring</span><span style="font-size: 10.5pt; color: #323432; font-family: 宋体">声明式事务管理的配置中，事务传播行为是最容易被误解的配置项，原因在于事务传播行为名称（如</span><span style="font-size: 10.5pt; color: #323432; font-family: Verdana">PROPAGATION_NESTED</span><span style="font-size: 10.5pt; color: #323432; font-family: 宋体">：嵌套式事务）和代码结构的类似性上（业务类方法嵌套调用另一个业务类方法）。这种误解在很多</span><span style="font-size: 10.5pt; color: #323432; font-family: Verdana">Spring</span><span style="font-size: 10.5pt; color: #323432; font-family: 宋体">开发者中广泛存在，本文深入讲解了</span><span style="font-size: 10.5pt; color: #323432; font-family: Verdana">Spring</span><span style="font-size: 10.5pt; color: #323432; font-family: 宋体">事务传播行为对业务方法嵌套调用的真实影响，希望能帮助读者化解对事务传播行为的困惑。</span>
<img src ="http://www.blogjava.net/msmary/aggbug/155395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-23 21:26 <a href="http://www.blogjava.net/msmary/articles/155395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>控制反转比喻(转)</title><link>http://www.blogjava.net/msmary/articles/151861.html</link><dc:creator>谭明</dc:creator><author>谭明</author><pubDate>Wed, 10 Oct 2007 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/msmary/articles/151861.html</guid><wfw:comment>http://www.blogjava.net/msmary/comments/151861.html</wfw:comment><comments>http://www.blogjava.net/msmary/articles/151861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/msmary/comments/commentRss/151861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/msmary/services/trackbacks/151861.html</trackback:ping><description><![CDATA[<div class="cnt" style="color: #800080">套用好莱坞的一句名言就是：你呆着别动，到时我会找你。 <br />
什么意思呢？就好比一个皇帝和太监 <br />
有一天皇帝想幸某个美女，于是跟太监说，今夜我要宠幸美女 <br />
皇帝往往不会告诉太监，今晚几点会回宫，会回哪张龙床，他只会告诉太监他要哪位美女 <br />
其它一切都交由太监去安排，到了晚上皇帝回宫时，自然会有美女出现在皇帝的龙床上 <br />
这就是控制反转，而把美女送到皇帝的寝宫里面去就是注射 <br />
太监就是是框架里面的注射控制器类BeanFactory，负责找到美女并送到龙床上去 <br />
整个后宫可以看成是Spring框架，美女就是Spring控制下的JavaBean <br />
而传统的模式就是一个饥渴男去找小姐出台 <br />
找领班，帮助给介绍一个云云，于是领班就开始给他张罗 <br />
介绍一个合适的给他，完事后，再把小姐还给领班，下次再来 <br />
这个过程中，领班就是查询上下文Context，领班的一个职能就是给客户找到他们所要的小姐 <br />
这就是lookup()方法，领班手中的小姐名录就是JNDI//Java Naming and Directory Interface <br />
小姐就是EJB，饥渴男是客户端，青楼是EJB容器 <br />
看到区别了么？饥渴男去找小姐出台很麻烦，不仅得找，用完后还得把小姐给还回去 <br />
而皇帝爽翻了，什么都不用管，交给太监去处理，控制权转移到太监手中去了 <br />
而不是皇帝，必要时候由太监给注射进去就可以了 <br />
看到Spring的美妙了吧，Spring还提供了与多个主流框架的支持 <br />
可以和其它开源框架集成 </div>
<img src ="http://www.blogjava.net/msmary/aggbug/151861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/msmary/" target="_blank">谭明</a> 2007-10-10 20:38 <a href="http://www.blogjava.net/msmary/articles/151861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>