zoukankan      html  css  js  c++  java
  • JAVA框架 Spring 事务

    一、我们之前在hibernate的时候,需要直接写事务,需要绑定当前线程保证获取同一个连接,虽然hibernate的帮我们封装绑定当前现成的操作,但是需要我们手动的去开启和关闭事务。

    而spring帮我们自动管理事务。

    二:事务:

    spring 事务的隔离级别的定义:
       TransactionDefinition
            1. 事务隔离级别的常量
                * static int ISOLATION_DEFAULT                     -- 采用数据库的默认隔离级别
                * static int ISOLATION_READ_UNCOMMITTED
                * static int ISOLATION_READ_COMMITTED
                * static int ISOLATION_REPEATABLE_READ
                * static int ISOLATION_SERIALIZABLE

    PROPAGATION(propagation)传播的意思。

    因为复杂的业务层之间的调用的话,会出现一个情况就是在业务方法中调用另一个业务方法,而这2个方法之间有事务的操作,针对这种情况,出现了事务的传递行为。

    作用:解决业务之间的方法调用

    需要掌握的:

          1)PROPAGATION_REQUIRED(默认值):A B两个方法,A中有事务使用A的事务,如果没有B方法开启一个新的事务将A包含进来(B调用A的方法,保证AB在同一个事务中)。这个是默认值。

          2)PROPAGATION_REQUIRES_NEW:--A中有事务,将A中的事务挂起,B创建一个新事物,(保证A B没有在同一个事务)。

          3)PROPAGATION_NESTED(记):嵌套事务,当A执行之后,就会在这个位置设置一个保存点,如果B没有问题,执行通过,如果B出现异常,运行客户根据需求回滚(选择保存丶或者最初状态。)

    三、spring事务设置:

    接口:1)PlatformTransactionManager:platform平台,即平台事务管理器,该接口有实现类,根据不同的持久框架选择不同的实现类,我们需要关注的是:DataSourceTransactionManager和HibernateTransactionManager

      

      2)TransactionDefinition接口:事务定义信息(事务的隔离级别、传播行为、超时、只读等。)

      3)TransactionStatus接口:事务的状态

    总结:上述对象之间的关系:平台事务管理器是真正管理事务的对象的。跟实物的定义信息(transactiondefinition)进行事务的管理,在管理事务中产生一些状态,将状态记录到transactionstatus中。

    声明事务方式:两种方式:1)XML配置文件方式、

         2)注解方式。

    XML配置文件方式:

     1、

      将事务管理器注入到spring中:因为我们使用的jdbc所有使用DataSourceTransactionManager

    1     <!--配置事务管理器-->
    2     <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager" >
    3         <property name="dataSource" ref="dataSource"/>
    4     </bean>

      需要设置dataSource属性值。

    1     <property name="dataSource" ref="dataSource"/>

     2、配置事务增强:

    1     <tx:advice id="interceptor" transaction-manager="dataSourceTransactionManager">
    2         <tx:attributes>
    3             <tx:method name="toaccount"/>
    4         </tx:attributes>
    5     </tx:advice>

    注意:1)、使用标签<tx:advice>  子标签<tx:attributes> attributes说明可以配置多个tx:method 也就是说可以同时给多个service层的方法添加事务。

       2)、标签:<tx:method> name属性为需要给那个方法添加事务。  propagation属性 传播行为采用Require 默认值(PROPAGATION_REQUIRED),isolation:事务级别,采取默认值,采用本地数据库事务级别。该标签可以写:<tx:method name="toaccount"/> 即可其他的传播行为和

    事务级别采用默认值。

       3)、transaction-manager属性是引用那个平台事务管理器的id值,我们使用的jdbc的事务管理器。

    3、配置AOP切面:

    1 <!--配置切面-->
    2     <aop:aspectj-autoproxy expose-proxy="true"/>
    3     <aop:config>
    4         <aop:advisor advice-ref="interceptor"  pointcut="execution(public  * jd.com.UserService.UserServiceImpl.toaccount(..))"/>
    5     </aop:config>

      1)开启动态代理。

    1     <aop:aspectj-autoproxy expose-proxy="true"/>

      2)配置切面:使用标签<aop:config> 

    1     <aop:config>
    2         <aop:advisor advice-ref="interceptor"  pointcut="execution(public  * jd.com.UserService.UserServiceImpl.toaccount(..))"/>
    3     </aop:config>

      3)注意:我们自己的写增强或者切面类的时候使用<aop:aspect>标签,使用的别人的增强的时候使用<aop:advisor>.

    4)编写测试类:

     1 package jd.com.UserService;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.test.context.ContextConfiguration;
     6 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     7 
     8 import javax.annotation.Resource;
     9 
    10 
    11 @RunWith(SpringJUnit4ClassRunner.class)
    12 @ContextConfiguration("classpath:applicationContext.xml")
    13 public class TestDemo {
    14 
    15     @Resource(name= "userService")
    16     private UserService userService;
    17 
    18 
    19     @Test
    20     public  void  add(){
    21         System.out.println(11111113);
    22         System.out.println(this.userService);
    23         this.userService.toaccount(111,222);
    24     }
    25 }

    service层:

     1 package jd.com.UserService;
     2 
     3 
     4 import jd.com.UserDao.userdao;
     5 import org.springframework.stereotype.Service;
     6 
     7 import javax.annotation.Resource;
     8 
     9 
    10 public class UserServiceImpl implements UserService {
    11 
    12     private userdao userdaoIMpl;
    13 
    14     public void setUserdaoIMpl(userdao userdaoIMpl) {
    15         this.userdaoIMpl = userdaoIMpl;
    16     }
    17 
    18     @Override
    19     public void toaccount(int mon1, int mon2) {
    20 
    21         System.out.println(this.userdaoIMpl);
    22         userdaoIMpl.addMoney(mon1);
    23         userdaoIMpl.delMoney(mon2);
    24     }
    25 }

    持久层:

     1 package jd.com.UserDao;
     2 
     3 
     4 import javafx.scene.chart.ValueAxis;
     5 import org.apache.commons.dbcp.BasicDataSource;
     6 import org.springframework.jdbc.core.support.JdbcDaoSupport;
     7 import org.springframework.stereotype.Repository;
     8 
     9 import javax.annotation.Resource;
    10 
    11 
    12 
    13 public class userdaoIMpl extends JdbcDaoSupport implements userdao  {
    14 
    15 
    16     @Override
    17     public void addMoney(int mon) {
    18         System.out.println(this.getDataSource());
    19         System.out.println(this.getJdbcTemplate());
    20         this.getJdbcTemplate().update(" UPDATE t_account SET money = money-? WHERE id = ? ",mon,1);
    21 
    22     }
    23 
    24     @Override
    25     public void delMoney(int mon) {
    26         this.getJdbcTemplate().update(" UPDATE t_account SET money = money+? WHERE id = ? ",mon,2);
    27     }
    28 }

     2、第二种方法:注解方式

    1)开启注解

    1     <!--开启注解-->
    2     <tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
    3 <!--配置切面-->

     2)配置管理器:

    1     <!--配置事务管理器-->
    2     <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager" >
    3         <property name="dataSource" ref="dataSource"/>
    4     </bean

    3)在目标类或者目标方法加注解:

     1 import jd.com.UserDao.userdao;
     2 import org.springframework.stereotype.Service;
     3 import org.springframework.transaction.annotation.Isolation;
     4 import org.springframework.transaction.annotation.Propagation;
     5 import org.springframework.transaction.annotation.Transactional;
     6 
     7 import javax.annotation.Resource;
     8 
     9 
    10 public class UserServiceImpl implements UserService {
    11 
    12     private userdao userdaoIMpl;
    13 
    14     public void setUserdaoIMpl(userdao userdaoIMpl) {
    15         this.userdaoIMpl = userdaoIMpl;
    16     }
    17 
    18     @Transactional(isolation= Isolation.DEFAULT ,propagation = Propagation.REQUIRED)
    19     @Override
    20     public void toaccount(int mon1, int mon2) {
    21 
    22         System.out.println(this.userdaoIMpl);
    23         userdaoIMpl.addMoney(mon1);
    24         userdaoIMpl.delMoney(mon2);
    25     }
    26 }

     可以在注解内设置相应的参数 如果不设置可以直接使用@Transactional

    1 @Transactional(isolation= Isolation.DEFAULT ,propagation = Propagation.REQUIRED)

    也可以在类上加注解,那这个类下面的所有方法都受事务影响。

  • 相关阅读:
    CentOS7.2上安装Python3.6
    Ubuntu 18.04 安装配置 MySQL 5.7
    CentOS 使用 sudo 遇到 command not found 问题解决
    一个恼人的文件名问题
    CentOS7 安装配置备忘录
    Win7 + CentOS7 双系统
    C++ 精英化趋势
    CentOS7 安装配置 MySQL 5.7
    pip "Cannot uninstall 'six'. It is a distutils installed project..." 解决方法
    Linux 系统假死的解决方案
  • 原文地址:https://www.cnblogs.com/evilliu/p/8906827.html
Copyright © 2011-2022 走看看