zoukankan      html  css  js  c++  java
  • 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 企业应用实战》

  • 相关阅读:
    栈和队列
    数组的遍历查找
    字符串的子串
    两个字符串
    字符串的遍历
    字符串的替换
    数组和矩阵
    Django 自带的ORM增删改查
    what's the CRSF ??
    Rabbitmq -Publish_Subscribe模式- python编码实现
  • 原文地址:https://www.cnblogs.com/jbelial/p/2533212.html
Copyright © 2011-2022 走看看