自然

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿(6)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔分类

  • mobile (rss)
  • Project Summary (rss)

随笔档案

  • 2012年2月 (2)
  • 2011年2月 (1)
  • 2010年12月 (3)
  • 2010年2月 (1)
  • 2009年7月 (1)
  • 2009年6月 (1)
  • 2009年5月 (1)
  • 2009年4月 (1)
  • 2009年2月 (1)
  • 2008年11月 (3)
  • 2008年7月 (1)
  • 2008年3月 (1)
  • 2008年2月 (1)
  • 2008年1月 (1)
  • 2007年10月 (1)
  • 2007年3月 (2)

文章分类

  • Architecture(4) (rss)
  • bank(6) (rss)
  • Class&ClassLoader&-------(8) (rss)
  • client&demand(4) (rss)
  • Construct(1) (rss)
  • DataBase(7) (rss)
  • EJB(2) (rss)
  • Hibernate(2) (rss)
  • integration(2) (rss)
  • jar_build_version_and(3) (rss)
  • java(2) (rss)
  • java glossary(18) (rss)
  • job(1) (rss)
  • JSF(4) (rss)
  • Log(8) (rss)
  • mobile (rss)
  • OSGI(1) (rss)
  • personality(3) (rss)
  • Project Summary(5) (rss)
  • remote(2) (rss)
  • search(3) (rss)
  • Server(3) (rss)
  • Speak(1) (rss)
  • Spring(7) (rss)
  • Struts(6) (rss)
  • test(2) (rss)
  • web(9) (rss)
  • 感悟(1) (rss)
  • 错误汇总(1) (rss)

文章档案

  • 2016年2月 (1)
  • 2015年10月 (1)
  • 2015年5月 (1)
  • 2015年4月 (2)
  • 2015年3月 (5)
  • 2015年2月 (5)
  • 2015年1月 (5)
  • 2011年4月 (1)
  • 2011年2月 (2)
  • 2010年8月 (1)
  • 2010年7月 (1)
  • 2010年6月 (3)
  • 2010年5月 (2)
  • 2010年2月 (1)
  • 2009年7月 (7)
  • 2008年10月 (2)
  • 2008年6月 (3)
  • 2008年5月 (3)
  • 2008年2月 (5)
  • 2008年1月 (2)
  • 2007年12月 (3)
  • 2007年8月 (4)
  • 2007年7月 (5)
  • 2007年6月 (14)
  • 2007年5月 (10)
  • 2007年4月 (16)
  • 2007年3月 (10)

搜索

  •  

最新评论

  • 1. re: Spring 中的数据源
  • 评论内容较长,点击标题查看
  • --zuidaima
  • 2. re: CFCA 数字证书的安装与使用(转)
  • -----------------
  • --姜艳丽
  • 3. re: CFCA 数字证书的安装与使用(转)
  • ----------
  • --姜艳丽
  • 4. re: 怎么变成熟!(转)
  • 方法:其实成熟说到底是做事和做人,没什么捷径可走的, 谢谢字典啊
  • --吴文兴
  • 5. re: javascript正则表达式对象
  • 不错
  • --咱

阅读排行榜

  • 1. 泰山_歌词(343)
  • 2. 对象&过程(311)
  • 3. 简单的道理(299)
  • 4. 我的英语第一次(291)
  • 5. 温暖的时光(276)

评论排行榜

  • 1. 稻盛箴言(0)
  • 2. 内心语录(0)
  • 3. 泰山_歌词(0)
  • 4. 深圳_我的关键词(0)
  • 5. 温暖的时光(0)

Powered by: 博客园
模板提供:沪江博客
BlogJava | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

spring事务相关(转)

spring事务管理

通常通过TransactionProxyFactoryBean设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。 事务属性含有上面描述的事务定义。
<bean id="petStore" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="target"><ref bean="petStoreTarget"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>

事务代理会实现目标对象的接口:这里是id为petStoreTarget的bean。(使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。如果目标对象没有实现任何接口,这将自动设置该属性为true。通常,我们希望面向接口而不是类编程。)使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的(一般来说是个好想法)。也可以通过从 org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享 的属性来定制TransactionProxyFactoryBean的行为。

这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类,事务将 会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚,+前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务,当然你自己要明白自己 在做什么)。

TransactionProxyFactoryBean允许你通过 “preInterceptors”和“postInterceptors”属性设置“前”或“后”通知来提供额外的 拦截行为。可以设置任意数量的“前”和“后”通知,它们的类型可以是 Advisor(可以包含一个切入点), MethodInterceptor或被当前Spring配置支持的通知类型 (例如ThrowAdvice, AfterReturningtAdvice或BeforeAdvice, 这些都是默认支持的)。这些通知必须支持实例共享模式。如果你需要高级AOP特 性来使用事务,如有状态的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean实用代理创建者。

也可以设置自动代理:配置AOP框架,不需要单独的代理定义类就可以生成类的 代理。

附两个spring的事务配置例子:
<prop key="add">
     PROPAGATION_REQUIRES_NEW, -MyException
</prop>
注:上面的意思是add方法将独占一个事务,当事务处理过程中产生MyException异常或者该异常的子类将回滚该事务。

<prop key="loadAll">
    PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly
</prop>
注:表示loadAll方法支持事务,而且不会读取没有提交事务的数据。它的数据为只读(这样有助于提高读取的性能)

附A Spring中的所有事务策略

PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED_NEW
PROPAGATION_SUPPORTS

附B Spring中所有的隔离策略:

ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITED
ISOLATION_COMMITED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE

Spring事务类型祥解

大家可能在spring中经常看到这样的定义:

 

<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop><prop key="store*">PROPAGATION_REQUIRED</prop>

估计有好多朋友还没有弄清楚里面的值的意思,仔细看完下面应该知道自己什么情况下面应该使用什么样的声明。^_^

 

Spring中常用事务类型:

  • PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
摘要:
Spring和EJB一样,提供了两种事务管理方式:编程式和声明式。在考试系统中我们将使用声明式的事务管理,这是spring推荐的做法。使用这种方式可以体验到spring的强大便捷,而且我们无须在Dao类中编写任何特殊的代码,只需要通过配置文件就可以让普通的java类加载到事务管理中,这个意义是很重大的。


本文Matrix永久镜像:http://www.matrix.org.cn/resource/article/1/1339.html
说明:本文可能由Matrix原创,也可能由Matrix的会员整理,或者由
Matrix的Crawler在全球知名Java或者其他技术相关站点抓取并永久
保留镜像,Matrix会保留所有原来的出处URL,并在显著地方作出说明,
如果你发觉出处URL有误,请联系Matrix改正.
四、Spring中的事务控制

Spring和EJB一样,提供了两种事务管理方式:编程式和声明式。在考试系统中我们将使用声明式的事务管理,这是spring推荐的做法。使用这种方式可以体验到spring的强大便捷,而且我们无须在Dao类中编写任何特殊的代码,只需要通过配置文件就可以让普通的java类加载到事务管理中,这个意义是很重大的。

Spring中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,由于接口是延迟实例化的,spring在这段时间内通过拦截器,加载事务切片。原理就是这样,具体细节请参考jdk中有关动态代理的文档。本文主要讲解如何在spring中进行事务控制。

动态代理的一个重要特征是,它是针对接口的,所以我们的dao要通过动态代理来让spring接管事务,就必须在dao前面抽象出一个接口,当然如果没有这样的接口,那么spring会使用CGLIB来解决问题,但这不是spring推荐的方式,我们也不做讨论。

参照前面的例子,我们为StudentManager.java定义一个接口,它的内容如下:

/*
* 创建日期 2005-3-25
*/
package org.bromon.spring.examer.student;

import java.util.List;

import org.bromon.spring.examer.pojo.Student;

/**
* @author Bromon
*/
public interface StudentManagerInterface
{
    public void add(Student s);
    public void del(Student s);
    public void update(Student s);
   
    public List loadAll();
    public Student loadById(int id);
}

StudentManager也应该做出修改,实现该接口:

public class StudentManager extends HibernateDaoSupport implements StudentManagerInterface

现在需要修改配置文件,用于定义Hibrenate适用的事务管理器,并且把sessionFactory注入进去,同时还需要通过注册一个DefaultTransactionAttribute对象,来指出事务策略。其中sessionFactory的定义已经在本文的第三章中说明。

首先定义一个Hibernate的事务管理器,让它来管理sessionFactory:
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
      <property name="sessionFactory">
         <ref bean="sessionFactory"/>
      </property>
</bean>

下面定义事务管理策略,我们希望把策略定义在方法这个级别上,提供最大的灵活性,本例中将add方法定义为:PROPAGATION_REQUIRES_NEW,这可以保证它将始终运行在一个事务中。

<bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
      <property name="properties">
         <props>
            <prop key="add">
               PROPAGATION_REQUIRES_NEW
            </prop>
         </props>
      </property>
   </bean>

我们不仅可以为add方法定义事务策略,还可以定义事务隔离程度和回滚策略,他们以逗号隔开,比如我们的add事务可以定义为:

<prop key="add">
   PROPAGATION_REQUIRES_NEW,-ExamerException
</prop
>

这个事务策略表示add方法将会独占一个事务,当事务过程中产生ExamerException异常,事务会回滚。

Add/update/del都是写入方法,对于select(读取)方法,我们可以指定较为复杂的事务策略,比如对于loadAll()方法:

<prop key=”loadAll”>
      PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly
   </prop>


该事务的含义为,loadAll方法支持事务,不会读去位提交的数据,它的数据为只读(可提高执行速度)。

如你所见,我们的StudentManagerInterface接口中还有一个loadById(int id)方法,也许我们将来还会有很多的loadByXXXX的方法,难道要意义为他们指定事务策略?太烦人了,他们应该和loadAll()一样,所以我们可以使用通配符,定义所有的loadXXXX方法:

<prop key=”load*”>
      PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly
   </prop>


现在可以定义事务管理器:
<bean id="studentManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
      <property name="target">
         <ref bean="studentManager"/>
      </property>
      <property name="transactionManager">
         <ref bean="transactionManager"/>
      </property>
      <property name="transactionAttributeSource">
         <ref bean="transactionAttributeSource"/>
      </property>
</bean>


这个bean的外观是一个接口(StudentManagerInterface),我们指出了它的具体实现(studentManager),而且为它绑定了事务策略。在客户端使用的时候,获得对象是StudentManagerInterface,所有的操作都是针对这个接口的。测试代码并没有改变,我们虽然修改了很多地方,加入了事务控制,但是客户端并没有受到影响,这也体现了spring的一些优势。测试代码如下:

public void testAdd() 
    {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("springConfig.xml");
        StudentManager sm=(StudentManager)ctx.getBean("studentManager");
       
        Student s=new Student();
        s.setId(1);
        s.setName("bromon");
        s.setPassword("123");
        s.setGrade(1);
        s.setSex(0);
       
        sm.add(s);
}


通过以上的代码可以看出,spring可以简单的把普通的java class纳入事务管理,声明性的事务操作起来也很容易。有了spring之后,声明性事务不再是EJB独有,我们不必为了获得声明性事务的功能而去忍受EJB带来的种种不便。

我所使用的mysql是不支持事务的,你可以更换使用PostgreSQL,有了spring+hibernate,更换db并不像以前那样恐怖了,步骤很简单:

1、 添加PostgreSQL的jdbc驱动
2、 修改dataSource配置,包括驱动名称、url、帐号、密码
3、 修改sessionFactory的数据库dailet为net.sf.hibernate.dialect.PostgreSQLDialect
4、 修改hbm.xml中的主键生成策略为increment

所有的修改都在配置文件中完成,业务代码不需要任何修改,我很满意,How about u?

 

 

spring声明式事务管理的两种方式

传统的:
 1 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 2         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
 3         <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:dev" />
 4         <property name="username" value="kaktos" />
 5         <property name="password" value="kaktos" />
 6     </bean>
 7 
 8     <bean id="txManager"
 9         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
10         <property name="dataSource" ref="dataSource" />
11     </bean>
12 
13     <bean id="businessBean"
14         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
15         <property name="transactionManager" ref="txManager" />
16         <property name="target" ref="businessBeanTarget" />
17         <property name="transactionAttributes">
18             <props>                
19                 <prop key="*">PROPAGATION_REQUIRED</prop>
20             </props>
21         </property>
22     </bean>
23     
24     <bean id="businessBeanTarget" class="sample.spring.trans.BusinessBean">
25         <property name="dataSource" ref="dataSource" />
26     </bean>

这样做的弊端就是不得不为每个需要事务的bean做一次声明,如果所有的bean都基本上有一致的配置,这样就太繁琐啦。
下面是第二种方式:
 1 <beans>
 2     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 3         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
 4         <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:dev" />
 5         <property name="username" value="kaktos" />
 6         <property name="password" value="kaktos" />
 7     </bean>
 8 
 9     <bean id="txManager"
10         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
11         <property name="dataSource" ref="dataSource" />
12     </bean>
13 
14     <bean id="matchAllWithPropReq"
15         class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
16         <property name="transactionAttribute" value="PROPAGATION_REQUIRED" />
17     </bean>
18     
19     <bean id="matchAllTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
20         <property name="transactionManager" ref="txManager" />
21         <property name="transactionAttributeSource" ref="matchAllWithPropReq" />
22     </bean>
23 
24     <bean id="autoProxyCreator"
25         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
26         <property name="interceptorNames">
27             <list>
28                 <idref local="matchAllTxInterceptor" />
29             </list>
30         </property>
31         <property name="beanNames">
32             <list>
33                 <idref local="businessBean" />
34             </list>
35         </property>
36     </bean>
37     
38     <!--  my beans  -->
39     <bean id="businessBean" class="sample.spring.trans.BusinessBean">
40         <property name="dataSource" ref="dataSource" />
41     </bean>
42 </beans>

BeanNameAutoProxyCreator会在applicationcontext初始化后自动为beanNames属性中的bean建立proxy。
发表于 2008-06-06 11:12 Masen 阅读(188) 评论(0)  编辑  收藏 所属分类: Spring
 
新用户注册  刷新评论列表  

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问   管理
相关文章:
  • Spring事务管理器的应对 (转)
  • Spring声明式事务管理与配置详解(转)
  • cron 表达式的格式 (转http://www.blogjava.net/Unmi/archive/2008/02/23/181575.html,作者:隔叶黄莺)
  • 详解spring事务属性(转)
  • spring事务相关(转)
  • jamon
  • Spring 中的数据源