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)

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

  • 相关阅读:
    C#磁吸屏幕窗体类库
    准备
    我写的诗
    How to turn off a laptop keyboard
    How to tell which commit a tag points to in Git?
    Why should I care about lightweight vs. annotated tags?
    How to get rid of “would clobber existing tag”
    Facebook, Google and Twitter threaten to leave Hong Kong over privacy law changes
    The need for legislative reform on secrecy orders
    Can a foreign key be NULL and/or duplicate?
  • 原文地址:https://www.cnblogs.com/evilliu/p/8906827.html
Copyright © 2011-2022 走看看