Spring 事务支持

  Spring 的事务管理不需要 与任何特定的事务API耦合。

  Spring同时支持编程式事务策略和声明式事务策略,声明式事务管理的配置方法有下面四种:

  1、使用TransactionProxyFactoryBean为目标Bean生成事务代理的配置。

  2、采用Bean继承的事务代理配置方法。

  3、采用BeanNameAutoProxyCreator , 根据Bean Name 自动生成事务代理的方式。这是直接利用Spring 的AOP框架配置事务代理的方式。

  4、采用DefaultAdvisorAutoProxyCreator,直接利用Spring 的AOP框架配置事务代理的方式。

 

 

1、使用TransactionProxyFactoryBean为目标Bean生成事务代理的配置

  采用这种方式的配置。每一个Bean需要两个Bean配置,一个是目标Bean,一个是使用TransactionProxyFactoryBean 配置的一个代理Bean。事务代理的方法改写了目标Bean的方法,就在目标Bean的方法执行前加入开始事务,在目标Bean的方法正常结束之前提交事务,如果遇到特定异常则回滚事务。

  TransactionProxyFactoryBean 创建事务代理时,需要了解当时事务所处的环境,该该环境属性通过PlateTransactionManager 实例(其实现类的实例)传入,而相关事务规则则在该Bean定义中给出。

  

import javax.sql.DataSource;
import java.sql.Connection;

import org.springframework.jdbc.core.JdbcTemplate; /**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class NewDaoImp1 implements NewDao
{
    private DataSource ds;
    public void setDs(DataSource ds)
    {
        this.ds = ds;
    }
    public void insert(String title , String content)
    {
        JdbcTemplate jt = new JdbcTemplate(ds);
        jt.update("insert into news_inf"
            + " values(null , ? , ?)" 
            , title , content);
        //两次插入的数据违反唯一键约束
        jt.update("insert into news_inf"
            + " values(null , ? , ?)" 
            , title , content);
        //如果增加事务控制,我们发现第一条记录也插不进去。
        //如果没有事务控制,则第一条记录可以被插入
    }
}

  如果在没有事务控制的环境下,前一条代码将会想数据库插入一条记录;但如果添加了事务控制的环境下,则这两条语句是一个整体,因为第二条语句插入失败

,所以将导致第一条语句插入的数据也被回滚。

  并使用TransactionProxyFactoryBean为它配置事务代理:

  

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   ...
    <!-- 配置JDBC数据源的局部事务管理器,使用DataSourceTransactionManager 类 -->
    <!-- 该类实现PlatformTransactionManager接口,是针对采用数据源连接的特定实现-->
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 配置DataSourceTransactionManager时需要依注入DataSource的引用 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置一个业务逻辑Bean -->
    <bean id="newsDao" class="org.crazyit.app.dao.impl.NewsDaoImpl">
        <property name="ds" ref="dataSource"/>
    </bean>
    <!-- 为业务逻辑Bean配置事务代理 -->
    <bean id="newsDaoTrans" class=
    "org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!-- 为事务代理工厂Bean注入事务管理器 -->
        <property name="transactionManager" ref="transactionManager"/> 
        <property name="target" ref="newsDao"/>
        <!-- 指定事务属性 -->
        <property name="transactionAttributes"> 
            <props> 
                <prop key="*">PROPAGATION_REQUIRED</prop> 
            </props>
        </property>
    </bean> 
</beans>

  配置事务代理时需要传入一个事务管理器、一个目标Bean,并指定该事务代理的事务属性,事务属性由transactionAttrubuters 属性指定。上面的事务属性只有一条事务传播规则,该规则指定对于所有方法都使用PROPAGATION_REQUIRED的传播规则。

  PROPAGATION_REQUIRED:要求在事务环境中执行该方法,如果当前执行线程已处于事务中,则直接调用;如果当前执行线程不处于事务中,则启动新的事务后执行该方法。

package lee;

import org.springframework.context.support.*;
import org.springframework.context.*;

import org.crazyit.app.dao.*;
/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class SpringTest
{
    public static void main(String[] args) 
    {
        //创建Spring容器
        ApplicationContext ctx = new 
            ClassPathXmlApplicationContext("bean.xml");
        //获取事务代理Bean
        NewsDao dao = (NewsDao)ctx
            .getBean("newsDaoTrans" , NewsDao.class);
        //执行插入操作
        dao.insert("疯狂Java" , "轻量级Java EE企业应用实战");
    }
}

  参考《轻量级java EE 企业应用实战》

posted @ 2012-06-03 21:39  贺佐安  阅读(2387)  评论(1编辑  收藏  举报