﻿<?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-fjpan2002-文章分类-Spring</title><link>http://www.blogjava.net/fjpan2002/category/3567.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 06:47:01 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 06:47:01 GMT</pubDate><ttl>60</ttl><item><title>Spring事务</title><link>http://www.blogjava.net/fjpan2002/articles/21096.html</link><dc:creator>勇敢的心</dc:creator><author>勇敢的心</author><pubDate>Wed, 23 Nov 2005 02:36:00 GMT</pubDate><guid>http://www.blogjava.net/fjpan2002/articles/21096.html</guid><wfw:comment>http://www.blogjava.net/fjpan2002/comments/21096.html</wfw:comment><comments>http://www.blogjava.net/fjpan2002/articles/21096.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/fjpan2002/comments/commentRss/21096.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/fjpan2002/services/trackbacks/21096.html</trackback:ping><description><![CDATA[Spring中事务的定义：<BR>一、Propagation ：<BR><BR>对于特定的方法或方法命名模式，代理的具体事务行为由事务属性驱动，如下面的例子所示：<BR>&lt;prop key="load*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;<BR>&lt;prop key="store*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt; 
<P>　　key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用：</P>
<UL>
<LI>PROPAGATION_REQUIRED--支持当前事务，如果当前没有事务，就新建一个事务。这是最常见的选择。 
<LI>PROPAGATION_SUPPORTS--支持当前事务，如果当前没有事务，就以非事务方式执行。 
<LI>PROPAGATION_MANDATORY--支持当前事务，如果当前没有事务，就抛出异常。 
<LI>PROPAGATION_REQUIRES_NEW--新建事务，如果当前存在事务，把当前事务挂起。 
<LI>PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作，如果当前存在事务，就把当前事务挂起。 
<LI>PROPAGATION_NEVER--以非事务方式执行，如果当前存在事务，则抛出异常。 </LI></UL>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;前六个策略类似于EJB CMT：常量名相同，因此，对EJB开发人员来说，应该立刻就感到熟悉。第七个（PROPAGATION_NESTED）是Spring所提供的一个特殊变量。它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为（如Spring的DataSourceTransactionManager），或者通过JTA支持嵌套事务。</P>
<P>　　　　</P>
<P>二、Isolation Level(事务隔离等级):<BR>1、Serializable：最严格的级别，事务串行执行，资源消耗最大；<BR>2、<STRONG>REPEATABLE READ：</STRONG>保证了一个事务不会修改已经由另一个事务读取但未提交（回滚）的数据。避免了“脏读取”和“不可重复读取”的情况，但是带来了更多的性能损失。<BR>3、<STRONG>READ COMMITTED:</STRONG>大多数主流数据库的默认事务等级，保证了一个事务不会读到另一个并行事务已修改但未提交的数据，避免了“脏读取”。该级别适用于大多数系统。<BR>4、Read Uncommitted：保证了读取过程中不会读取到非法数据。<BR><BR>spring中的Isolation属性：<BR><SPAN class=fixed>1、ISOLATION_DEFAULT</SPAN> ：使用当前数据源的默认级别<BR><SPAN class=fixed>2、ISOLATION_READ_UNCOMMITTED</SPAN> ：Dirty reads, non-repeatable reads, and phantom reads can occur.<BR><SPAN class=fixed>3、ISOLATION_READ_COMMITTED</SPAN> :Dirty reads are prevented; non-repeatable reads and phantom reads can occur.<BR><SPAN class=fixed>4、ISOLATION_REPEATABLE_READ:Dirty reads and non-repeatable reads are prevented; phantom reads can occur.<BR><SPAN class=fixed>5、ISOLATION_SERIALIZABLE:Dirty reads, non-repeatable reads, and phantom reads are prevented.<BR><BR>三、readOnly<BR>事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这是一个最优化提示。在一些情况下，一些事务策略能够起到显著的最优化效果，例如在使用Object/Relational映射工具（如：Hibernate或TopLink）时避免dirty checking（试图“刷新”）。<BR><BR>四、Timeout</P></SPAN></SPAN>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在事务属性中还有定义“timeout”值的选项，指定事务超时为几秒。在JTA中，这将被简单地传递到J2EE服务器的事务协调程序，并据此得到相应的解释。<BR><BR>事务划分策略<BR><BR>1、推荐在业务层使用事务，这样可以允许业务层捕获导致rollback的异常，并抛出恰当的业务层异常；不在dao层使用事务是因为这会限制了dao重用其他事务需求，并且dao层没有实现业务逻辑，并且原子性也是业务层的概念。<BR><BR>spring声明性事务的划分：<BR>1、有四个地方需要配置：The four participants are transaction manager, proxy factory, transaction interceptor, and a set of transaction attributes.<BR><IMG src="mk:@MSITStore:D:\panxinyang\study\spring\Wrox.Professional.Java.Development.with.the.Spring.Framework.chm::/11235/images/fig06%5F02%5F0%2Ejpg"><BR><BR><BR><BR>2、使用ProxyFactoryBean/Transaction Interceptor（<SPAN class=fixed>transactionInterceptor</SPAN>）配置spring事务<BR><BR>以下为配置实例：<BR></P><PRE class=programlisting>&lt;!-- The DBCP DataSource --&gt;
  &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close"&gt;
    &lt;property name="driverClassName"&gt;
      &lt;value&gt;${jdbc.driverClassName}&lt;/value&gt;
    &lt;/property&gt;
    &lt;property name="url"&gt;&lt;value&gt;${jdbc.url}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="username"&gt;&lt;value&gt;${jdbc.username}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="password"&gt;&lt;value&gt;${jdbc.password}&lt;/value&gt;&lt;/property&gt;
  &lt;/bean&gt;
   
  &lt;!-- The DAO class --&gt;
  &lt;bean id="dao" 
class="org.springframework.prospring.ticket.dao.jdbc.JdbcBoxOfficeDao"&gt;
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;
   
  &lt;!-- The transactionmanager to use for regular non JTA datasource --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="transactionManager"</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;</SPAN>
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;
   
  &lt;!-- TransactionInterceptor --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="transactionInterceptor" </SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.transaction.interceptor.TransactionInterceptor"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionManager"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ref bean="transactionManager"/&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionAttributeSource"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">org.springframework.prospring.ticket.service.BoxOffice.get*=PROPAGATION_SUPPORTS,re</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">adOnly</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">org.springframework.prospring.ticket.service.BoxOffice.allocate*=PROPAGATION_REQUIR</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">ED</SPAN>
      &lt;/value&gt;
    &lt;/property&gt;
  &lt;/bean&gt;  
   
  &lt;!-- Transactional proxy for the primary business object --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="boxOffice" </SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.aop.framework.ProxyFactoryBean"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="target"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ref local="boxOfficeTarget"/&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="proxyInterfaces"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;org.springframework.prospring.ticket.service.BoxOffice&lt;/value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="interceptorNames"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;transactionInterceptor&lt;/value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
  &lt;/bean&gt;  
   
  &lt;!-- Business Object --&gt;
  &lt;bean id="boxOfficeTarget" 
    class="org.springframework.prospring.ticket.service.BoxOfficeImpl"&gt;
    &lt;property name="boxOfficeDao"&gt;
      &lt;ref local="dao"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;</PRE>
<P>3、使用TransactionProxyFactoryBean配置spring事务<BR>以下为配置实例：</P><PRE class=programlisting>  &lt;!-- The DBCP DataSource --&gt;
  &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
        destroy-method="close"&gt;
    &lt;property name="driverClassName"&gt;
      &lt;value&gt;${jdbc.driverClassName}&lt;/value&gt;
    &lt;/property&gt;
    &lt;property name="url"&gt;&lt;value&gt;${jdbc.url}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="username"&gt;&lt;value&gt;${jdbc.username}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="password"&gt;&lt;value&gt;${jdbc.password}&lt;/value&gt;&lt;/property&gt;
  &lt;/bean&gt;
   
  &lt;!-- The DAO class --&gt;
  &lt;bean id="dao"
class="org.springframework.prospring.ticket.dao.jdbc.JdbcBoxOfficeDao"&gt;
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;
   
  &lt;!-- The transactionmanager to use for regular non JTA datasource --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="transactionManager"</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;</SPAN>
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;
   
  &lt;!-- Transactional proxy and the primary business object --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="boxOffice" </SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp; class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionManager"&gt;&lt;ref bean="transactionManager"/&gt;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="target"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class="org.springframework.prospring.ticket.service.BoxOfficeImpl"&gt;</SPAN>
        &lt;property name="boxOfficeDao"&gt;
          &lt;ref local="dao"/&gt;
        &lt;/property&gt; 
      &lt;/bean&gt;
    &lt;/property&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionAttributes"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;props&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="get*"&gt;PROPAGATION_SUPPORTS,readOnly&lt;/prop&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key="allocate*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/props&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
  &lt;/bean&gt;  </PRE>
<P>4、使用BeanNameAutoProxyCreator配置spring事务<BR>如果有大量的bean需要使用事物，那么只要在配置文件中提供bean name给BeanNameAutoProxyCreator，spring就会个给该bean提供事务代理，配置实例如下：<BR></P><PRE class=programlisting>  &lt;!-- The DBCP DataSource --&gt;
  &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
      destroy-method="close"&gt;
    &lt;property name="driverClassName"&gt;
      &lt;value&gt;${jdbc.driverClassName}&lt;/value&gt;
    &lt;/property&gt;
    &lt;property name="url"&gt;&lt;value&gt;${jdbc.url}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="username"&gt;&lt;value&gt;${jdbc.username}&lt;/value&gt;&lt;/property&gt;
    &lt;property name="password"&gt;&lt;value&gt;${jdbc.password}&lt;/value&gt;&lt;/property&gt;
  &lt;/bean&gt;
   
  &lt;!-- The DAO class --&gt;
  &lt;bean id="dao"
class="org.springframework.prospring.ticket.dao.jdbc.JdbcBoxOfficeDao"&gt;
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt;
   
  &lt;!-- The transactionmanager to use for regular non JTA datasource --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="transactionManager"</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;</SPAN>
    &lt;property name="dataSource"&gt;
      &lt;ref local="dataSource"/&gt;
    &lt;/property&gt; 
  &lt;/bean&gt; 
   
  &lt;!-- TransactionInterceptor --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;bean id="transactionInterceptor" </SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.transaction.interceptor.TransactionInterceptor"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionManager"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ref bean="transactionManager"/&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="transactionAttributeSource"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">org.springframework.prospring.ticket.service.BoxOffice.get*=PROPAGATION_SUPPORTS</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">,readOnly</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">org.springframework.prospring.ticket.service.BoxOffice.allocate*=</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">PROPAGATION_REQUIRED</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;</SPAN>
  &lt;/bean&gt;  
   
  &lt;!-- BeanNameAutoProxyCreator --&gt;
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&lt;bean id="autoProxyCreator" </SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;property name="interceptorNames"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;transactionInterceptor&lt;/value&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;/property&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;property name="beanNames"&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;idref local="boxOffice"/&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;</SPAN>
<SPAN style="BACKGROUND-COLOR: #c0c0c0">&nbsp;&nbsp;&lt;/property&gt;</SPAN>
&lt;/bean&gt;  
   
&lt;!-- Business Object --&gt;
&lt;bean id="boxOffice"
   class="org.springframework.prospring.ticket.service.BoxOfficeImpl"&gt;
  &lt;property name="boxOfficeDao"&gt;
    &lt;ref local="dao"/&gt;
  &lt;/property&gt; 
&lt;/bean&gt;</PRE><img src ="http://www.blogjava.net/fjpan2002/aggbug/21096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fjpan2002/" target="_blank">勇敢的心</a> 2005-11-23 10:36 <a href="http://www.blogjava.net/fjpan2002/articles/21096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>