zoukankan      html  css  js  c++  java
  • spring 事务

    一:事务的配置

    spring 事务管理有两种方式

    1.声明式事务管理,在要管理的方法上添加@Transactional  写在service 的实现类或者dao层都可以

    2.配置式事务管理,在要管理的方法前后织入事务通知

    spring 配置文件 spring_coer.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:mvc="http://www.springframework.org/schema/mvc" 
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
                            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
                            http://www.springframework.org/schema/mvc  
                            http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                            http://www.springframework.org/schema/context  
                            http://www.springframework.org/schema/context/spring-context.xsd
                                http://www.springframework.org/schema/aop   
                             http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
                             http://www.springframework.org/schema/tx 
                             http://www.springframework.org/schema/tx/spring-tx.xsd">
                             <!--Spring 整合mybaits-->
    <!-- 加载配置文件 -->
            <bean id="loadProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                    <property name="locations">
                        <list>
                            <value>classpath:db.properties</value>
                        </list>
                    </property>
            </bean>
    
        <!--配置注解扫描 use-default-filters 是扫描包括component 下的子注解 @service 等 -->
        <context:component-scan base-package="com.ssh"></context:component-scan>
        <!--sping 整合hibernate -->
    
      
        <!--定义basicDataSource数据源 -->
        <!-- org.apache.commons.dbcp2.datasources -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
            <!-- 指定连接数据库的驱动 -->
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <!-- 指定数据库所用的url -->
            <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/ssm"></property>
            <!--指定连接的用户名 -->
            <property name="user" value="root"></property>
            <!-- 指定连接的密码 -->
            <property name="password" value="123456"></property>
            <!-- 定义hibernate 的sessionFactory -->
        </bean>
     <!--                              方式一   声明式事务管理                                                    -->
        <tx:annotation-driven transaction-manager="transactionManager"/>



    <!-- spring 整合mybaits --> <!-- sprig 托管sqlSessionFactoryBean 作用:创建会话连接--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 加载mybaties 配置文件 --> <property name="configLocation" value="classpath:mybatisConfig.xml"/> <!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件--> <!-- <property name="mapperLocations" value="classpath:com/ssh/sqlmap/*Mapper.xml" /> --> </bean> <!-- spring 注入模板工具类--> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg> </bean>

    <!--                                              方式二,配置事务管理                                                                               -->
         <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>


    <!-- 定义事务的通知 --> 
      <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 指定传播规则 -->

          <tx:attributes> <tx:method name="cre*" read-only="false" propagation="REQUIRED"/>

          <tx:method name="ins*" read-only="false" propagation="REQUIRED"/>

          <tx:method name="upd*" read-only="false" propagation="REQUIRED"/>

          <tx:method name="del*" read-only="false" propagation="REQUIRED"/>

          <tx:method name="*" isolation="DEFAULT" read-only="true" />

      </tx:attributes>

    </tx:advice>


    <!-- 定义一个切面 -->
    <aop:config>
    <!--指定切入的位置-->
          <!-- 切入点:第一个* 代表类型 public private protect 要有空格 切入点表达式的使用规则:
          execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
          有“?”号的部分表示可省略的,modifers-pattern表示修饰符如public、protected等,
          ret-type-pattern表示方法返回类型, declaring-type-pattern代表特定的类,
          name-pattern代表方法名称, param-pattern表示参数,
          throws-pattern表示抛出的异常。在切入点表达式中,可以使用*来代表任意字符,用..来表示任意个参数
    -->

      <aop:pointcut id="bizMethod" expression="execution(* com.ssh.dao.*.*(..))"/>

          <!--将通知和切点编织在一起-->

           <aop:advisor advice-ref="txAdvice" pointcut-ref="bizMethod"/>

      </aop:config>

    </beans>

    方式一或者方式二选择其中一种

    1.采用声明的方式管理事务

    @Transactional(添加事务的传播策略和隔离方式)
    public void transfer(HashMap<String, Object> param) {
    // TODO Auto-generated method stub
    studentDao.updateOutMoney(param);
    studentDao.updateInMoney(param);
    }

    方式二:只要将要调用事务的方法申明为 ins*/upd*/cre*/del*   为前缀的方法即可

    事务没有提交解决办法:

    1.查看配置方式中切面的位置,execution(* com.ssh.dao.*.*(..))"  在dao包下所有类,所有方法前缀为 ins*/upd*/cre*/del* ,才会提交事务

    二:事务的回滚

    事务只有对unchecked 异常才能回滚,所以要分析事务的回滚,先分析异常的分类

    1.Exception 异常时所有异常的父类:包含checked 异常和unchecked 异常

      checked 异常是程序编译的时候显示的异常,要显示的捕获或者抛出,比如:类型强制转化异常

      unchecked  也称为运行时异常,是发生在客户端与服务器端交互的时候,没有能通过代码控制的异常,比如空指针异常,数组下标越界,违法的参数异常,数学异常

        /*
         * 测试事务的回滚
         */
        public void updTransferRollBack(HashMap<String, Object> param) {
            // TODO Auto-generated method stub
                studentDao.updateOutMoney(param);
                
            /*    
             //1.下标越界异常 
              int[] a=new int[3];
                System.out.println(a.length);
                    a[0]=1;
                    a[1]=2;
                    a[2]=3;
                    a[3]=4;
                    System.out.println(a);*/
                //2 空指针异常
                Integer a=null;
                System.out.println(a.toString());
                studentDao.updateInMoney(param);
        }
    //这两种方式都回回滚

    2. 事务的传播策略

      propagation  :

        

    1、Propagation.REQUIRED

    方法被调用时自动开启事务,在事务范围内使用则使用同一个事务,否则开启新事务。       

      2、Propagation.REQUIRES_NEW

    无论何时自身都会开启事务

      3、Propagation.SUPPORTS

    自身不会开启事务,在事务范围内则使用相同事务,否则不使用事务

      4、Propagation.NOT_SUPPORTED

    自身不会开启事务,在事务范围内使用挂起事务,运行完毕恢复事务

      5、Propagation.MANDATORY

    自身不开启事务,必须在事务环境使用否则报错

      6、Propagation.NEVER

    自身不会开启事务,在事务范围使用抛出异常

      7、Propagation.NESTED

    如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。需要JDBC3.0以上支持。

    测试传播方式

    //测试requred

    public
    void updTransferRollBack(HashMap<String, Object> param) { // TODO Auto-generated method stub studentDao.updateOutMoney(param); /* //1.下标越界异常 int[] a=new int[3]; System.out.println(a.length); a[0]=1; a[1]=2; a[2]=3; a[3]=4; System.out.println(a);*/ //2 空指针异常 /*Integer a=null; System.out.println(a.toString());*/ studentDao.updateInMoney(param);
    //A 测试事务是否回滚
    Integer a=null; System.out.println(a.toString()); updTestRequried(); } public void updTestRequried(){ Random random=new Random(); HashMap<String, Object> param=new HashMap<String, Object>(); param.put("inMoney", random.nextInt()); param.put("id2", "333"); studentDao.updateInMoney(param); }

    结果:当事务的传播方式设置为requred ,
    updTransferRollBack 已经是一个事务,所以 updTestRequried 不用创建一个新的事务,和 updTransferRollBack 方法共用一个事务
    ,所以当在 A 处添加一个RuntimeException 的时候,两个方法里面的sql都会回滚
    
    
  • 相关阅读:
    严重: Parse error in application web.xml file at jndi:/localhost/ipws/WEBINF/web.xml java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml
    Failed to install .apk on device 'emulator5554': timeout解决方法
    java.lang.NoClassDefFoundError:org.jsoup.Jsoup
    Conversion to Dalvik format failed: Unable to execute dex:解决方法
    apache Digest: generating secret for digest authentication ...
    Description Resource Path Location Type Project has no default.properties file! Edit the project properties to set one.
    android service随机自启动
    MVC3 安装部署
    EF 4.3 CodeBased 数据迁移演练
    SQL Server 2008开启sa账户
  • 原文地址:https://www.cnblogs.com/blogxiao/p/7718891.html
Copyright © 2011-2022 走看看