zoukankan      html  css  js  c++  java
  • Spring中的事务管理模块基础

                                  Spring中的事务管理

      事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户 程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

      简单点说,事务就是一组逻辑操作,这组逻辑操作拥有ACID4个属性规范:

    1. 原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。(要么成功,要么失败)
    2. 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
    3. 隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
    4. 持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

      也就是说事务的概念来源于对数据库的访问及操作,而事务并发问题使得事务管理成为了开发中必须关注的一个点。

      spring作为java开发的一个顶级的一站式开发框架,其中就包含了声明式事务的支持。详细如下图:

      

      事务中的几个重要属性:

      隔离问题:

    • 脏读:一个事务读到另一个事务没有提交的数据
    • 不可重复读:一个事务读到另一个事务已提交的数据(update)
    • 虚读(幻读):一个事务读到另一个事务已提交的数据(insert)

      隔离级别:

             read uncommitted:读未提交。存在3个问题

             read committed:读已提交。解决脏读,存在2个问题

             repeatable read:可重复读。解决:脏读、不可重复读,存在1个问题。

             serializable :串行化。都解决,单事务。

        

    • mysql 事务操作--简单:假设事务包含a,b,c,d4个数据库操作,那么这个事务的逻辑代码一般是这样
    • Connection conn = null;
      try{
        //1 获得连接
        conn = ...;
        //2 开启事务
        conn.setAutoCommit(false);
        A
        B
        C
        D
        //3 提交事务
        conn.commit();
      } catche(){
        //4 回滚事务
        conn.rollback();
      }
      Connection conn = null;
      try{
        //1 获得连接
        conn = ...;
        //2 开启事务
        conn.setAutoCommit(false);
        A
        B
        C
        D
        //3 提交事务
        conn.commit();
      } catche(){
        //4 回滚事务
        conn.rollback();
      }
      View Code
    • mysql 事务操作--Savepoint
    • 需求:AB(必须),CD(可选) 
      Connection conn = null;
      Savepoint savepoint = null;  //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
      try{
        //1 获得连接
        conn = ...;
        //2 开启事务
        conn.setAutoCommit(false);
        A
        B
        savepoint = conn.setSavepoint();
        C
        D
        //3 提交事务
        conn.commit();
      } catche(){
        if(savepoint != null){   //CD异常
           // 回滚到CD之前
           conn.rollback(savepoint);
           // 提交AB
           conn.commit();
        } else{   //AB异常
           // 回滚AB
           conn.rollback();
        }
      }
      View Code

       1.1    Spring中事务管理介绍

          1.1.1   导入jar包

             transaction  -->  tx

        

         1.1.2   三个顶级接口

    •  PlatformTransactionManager  平台事务管理器,spring要管理事务,必须使用事务管理器

            进行事务配置时,必须配置事务管理器

    • TransactionDefinition:事务详情(事务定义、事务属性),spring用于确定事务具体详情,

           例如:隔离级别、是否只读、超时时间 等

           进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。

    • TransactionStatus:事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。

           spring底层根据状态进行相应操作。

        1.1.3   PlatformTransactionManager  事务管理器

    •  导入jar包:需要时平台事务管理器的实现类

         

    •  常见的事务管理器

           DataSourceTransactionManager  ,jdbc开发时事务管理器,采用JdbcTemplate

           HibernateTransactionManager,hibernate开发时事务管理器,整合hibernate

    •  api详解

      TransactionStatus getTransaction(TransactionDefinition definition) ,事务管理器 通过“事务详情”,获得“事务状态”,从而管理事务。

      void commit(TransactionStatus status)  根据状态提交

      void rollback(TransactionStatus status) 根据状态回滚

         1.1.4   TransactionStatus

         

        1.1.5   TransactionDefinition

      

    •  传播行为:在两个业务之间如何共享事务。

      PROPAGATION_REQUIRED , required , 必须  【默认值】

           支持当前事务,A如果有事务,B将使用该事务。

           如果A没有事务,B将创建一个新的事务。

      PROPAGATION_SUPPORTS ,supports ,支持

           支持当前事务,A如果有事务,B将使用该事务。

           如果A没有事务,B将以非事务执行。

      PROPAGATION_MANDATORY,mandatory ,强制

           支持当前事务,A如果有事务,B将使用该事务。

           如果A没有事务,B将抛异常。

      PROPAGATION_REQUIRES_NEW , requires_new ,必须新的

           如果A有事务,将A的事务挂起,B创建一个新的事务

           如果A没有事务,B创建一个新的事务

      PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持

           如果A有事务,将A的事务挂起,B将以非事务执行

           如果A没有事务,B将以非事务执行

      PROPAGATION_NEVER ,never,从不

           如果A有事务,B将抛异常

           如果A没有事务,B将以非事务执行

      PROPAGATION_NESTED ,nested ,嵌套

           A和B底层采用保存点机制,形成嵌套事务。

    • 掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
    • 转账案例

    • 业务逻辑:甲方给乙方转账,甲方和乙方得账户应该同时改变,如果中途断电断网,那么就要考虑事务回滚了。
      • 创建数据库:
      • /*
        Navicat MySQL Data Transfer
        
        Source Server         : gg
        Source Host           : localhost:3306
        Source Database       : spring_database
        
        Target Server Type    : MYSQL
        File Encoding         : 65001
        
        Date: 2017-03-10 13:57:02
        */
        
        SET FOREIGN_KEY_CHECKS=0;
        
        -- ----------------------------
        -- Table structure for account
        -- ----------------------------
        DROP TABLE IF EXISTS `account`;
        CREATE TABLE `account` (
          `_id` int(32) NOT NULL AUTO_INCREMENT COMMENT '账户id',
          `username` varchar(32) NOT NULL COMMENT '账户名',
          `money` int(32) NOT NULL COMMENT '账户余额',
          PRIMARY KEY (`_id`)
        ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
        
        -- ----------------------------
        -- Records of account
        -- ----------------------------
        INSERT INTO `account` VALUES ('1', 'jake', '82000');
        INSERT INTO `account` VALUES ('2', 'make', '212000');
        INSERT INTO `account` VALUES ('3', 'tom', '879800');
        
        -- ----------------------------
        -- Table structure for t_user
        -- ----------------------------
        DROP TABLE IF EXISTS `t_user`;
        CREATE TABLE `t_user` (
          `_id` int(11) NOT NULL AUTO_INCREMENT,
          `username` varchar(50) DEFAULT NULL,
          `userpwd` varchar(32) DEFAULT NULL,
          PRIMARY KEY (`_id`)
        ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
        
        -- ----------------------------
        -- Records of t_user
        -- ----------------------------
        INSERT INTO `t_user` VALUES ('1', 'jake', '123456');
        INSERT INTO `t_user` VALUES ('2', 'rose', '123456789');
        INSERT INTO `t_user` VALUES ('3', 'tom', '999');
        INSERT INTO `t_user` VALUES ('4', 'tom', '999');
        INSERT INTO `t_user` VALUES ('5', 'tom', '362427');
        View Code

     

    • 环境搭建
    • 引入jar包:jar包下载地址:http://pan.baidu.com/s/1nvJOz6D
    • dao接口设计
    • package com.heima.dao;
      
      public interface AccountDao {
          /**
           * 汇款
           * @param outer
           * @param money
           */
          public void out(String outer, Integer money);
      
          /**
           * 收款
           * @param outer
           * @param money
           */
          public void in(String outer, Integer money);
      }
      View Code
    • dao具体实现类设计
    • package com.heima.dao.impl;
      
      import org.springframework.jdbc.core.support.JdbcDaoSupport;
      
      import com.heima.dao.AccountDao;
      
      public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
      
          @Override
          public void out(String outer, Integer money) {
              this.getJdbcTemplate().update("update account set money=money-? where username=?",money, outer);
          }
      
          @Override
          public void in(String outer, Integer money) {
              this.getJdbcTemplate().update("update account set money=money+? where username=?",money, outer);
              
          }
      
      }
      View Code
    • service接口设计

    • package com.heima.service;
      
      public interface AccountService {
          /**
           * 
           * @param outer 转账
           * @param inner 收款人
           * @param money 转账金额
           */
          public void transfer(String outer,String inner,Integer money);
      }
      View Code
    • service具体实现类设计
    • package com.heima.service.impl;
      
      import com.heima.dao.AccountDao;
      import com.heima.service.AccountService;
      
      public class AccountServiceImpl implements AccountService{
      
          private AccountDao accountdao;
          @Override
          public void transfer(String outer, String inner, Integer money) {
              accountdao.out(outer, money);
              
          /*    //断电
              int i = 1/0;*/
              accountdao.in(inner, money);
          }
          
          
          public AccountDao getAccountdao() {
              return accountdao;
          }
          public void setAccountdao(AccountDao accountdao) {
              this.accountdao = accountdao;
          }
      
      }
      View Code
    • application.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:aop="http://www.springframework.org/schema/aop"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop 
                                    http://www.springframework.org/schema/aop/spring-aop.xsd
                                    http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/context/spring-context.xsd">
          
      <!-- 加载jdbcinfo.properties文件 -->
      <context:property-placeholder location="classpath:jdbcinfo.properties"/>
      <!-- dataSource 数据源-->
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
          <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
          <property name="DriverClass" value="${jdbc.driverClass}"></property>
          <property name="user" value="${jdbc.user}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      <!-- dao -->
      <bean id="accountdao" class="com.heima.dao.impl.AccountDaoImpl">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      <!-- service -->
      <bean id="accountservice" class="com.heima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountdao"></property>
      </bean>
      </beans>
      View Code
    • jdbcinfo.properties
    • jdbc.driverClass=com.mysql.jdbc.Driver
      jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring_database
      jdbc.user=root
      jdbc.password=362427gg
      View Code
    • 测试:
    • package com.heima;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      import com.heima.service.AccountService;
      
      public class TestApp {
          
          @Test
          public void testdamo() {
              String xmlpath = "applicationContext.xml";
              ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlpath);
              AccountService service = applicationContext.getBean("accountservice",AccountService.class);
              service.transfer("jake", "make", 1000);
          }
      }
      View Code

      运行发现这样子的话一旦遇到了加入断电,断网异常时将会导致数据库不一致,也就是说例如:甲方账户转账成功给乙方后忽然断电而乙方账户没有加。

      解决这一问题的方法就是引入事务,让转账这一组操作成为一个事务。

      spring提供了申明式的事务支持,当然在这以前我们先使用编程式的方法解决这个问题:

    1. 使用spring自带的TransactionTemplate事务模板  

    1.service 需要获得 TransactionTemplate

    2.spring 配置模板,并注入给service

    3.模板需要注入事务管理器

    4.配置事务管理器:DataSourceTransactionManager ,需要注入DataSource

      修改serviceimpl为如下:

    • package com.heima.service.impl;
      
      import org.springframework.transaction.TransactionStatus;
      import org.springframework.transaction.support.TransactionCallbackWithoutResult;
      import org.springframework.transaction.support.TransactionTemplate;
      
      import com.heima.dao.AccountDao;
      import com.heima.service.AccountService;
      
      public class AccountServiceImpl implements AccountService{
      
          private AccountDao accountdao;
          private TransactionTemplate transtemplate;
          
          @Override
          public void transfer(String outer, String inner, Integer money) {
          
              transtemplate.execute(new TransactionCallbackWithoutResult() {
                  
                  @Override
                  protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                      accountdao.out(outer, money);
                      
                      //断电
                          int i = 1/0;
                          accountdao.in(inner, money);
                  }
              });
              
              
          }
          
          
          public AccountDao getAccountdao() {
              return accountdao;
          }
          public void setAccountdao(AccountDao accountdao) {
              this.accountdao = accountdao;
          }
      
      
          public TransactionTemplate getTranstemplate() {
              return transtemplate;
          }
      
      
          public void setTranstemplate(TransactionTemplate transtemplate) {
              this.transtemplate = transtemplate;
          }
      
      }
      View Code

       修改applicationContext.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:aop="http://www.springframework.org/schema/aop"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop 
                                    http://www.springframework.org/schema/aop/spring-aop.xsd
                                    http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/context/spring-context.xsd">
          
      <!-- 加载jdbcinfo.properties文件 -->
      <context:property-placeholder location="classpath:jdbcinfo.properties"/>
      <!-- dataSource -->
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
          <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
          <property name="DriverClass" value="${jdbc.driverClass}"></property>
          <property name="user" value="${jdbc.user}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      <!-- dao -->
      <bean id="accountdao" class="com.heima.dao.impl.AccountDaoImpl">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      <!-- 创建事务管理器,需要注入数据源从而拿到连接池对象获取事务管理器 -->
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSource"></property>
      </bean>
      <!-- 创建模板 -->
      <bean id="transtemplate" class="org.springframework.transaction.support.TransactionTemplate">
          <property name="transactionManager" ref="txManager"></property>
      </bean>
      
      <!-- service -->
      <bean id="accountservice" class="com.heima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountdao"></property>
          <property name="transtemplate" ref="transtemplate"></property>
      </bean>
      </beans>
      View Code

         运行可以发现一旦事务运行期间出错数据库将不会改变。保证了数据的一致性,符合正常的业务逻辑。

       2.使用spring的代理类org.springframework.transaction.interceptor.TransactionProxyFactoryBean

      service 代理对象

    •  proxyInterfaces 接口
    •  target 目标类
    •  transactionManager 事务管理器
    •  transactionAttributes 事务属性(事务详情)

                 prop.key :确定哪些方法使用当前事务配置

                 prop.text:用于配置事务详情

                      格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception

                          传播行为      隔离级别 是否只读      异常回滚      异常提交

                      例如:

                          <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认传播行为,和隔离级别

                          <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> 只读

                          <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.ArithmeticException</prop>  有异常扔提交

      实现逻辑就是:通过返回一个代理类去执行业务操作:

      将serviceimpl恢复到最原始的状态

    •   
      package com.heima.service.impl;
      
      import com.heima.dao.AccountDao;
      import com.heima.service.AccountService;
      
      public class AccountServiceImpl implements AccountService{
      
          private AccountDao accountdao;
          
          @Override
          public void transfer(String outer, String inner, Integer money) {    
                  accountdao.out(outer, money);
                  accountdao.in(inner, money);        
          }
          
          
          public AccountDao getAccountdao() {
              return accountdao;
          }
          public void setAccountdao(AccountDao accountdao) {
              this.accountdao = accountdao;
          }
      }
      View Code
    • applicationContext.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:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop 
                                    http://www.springframework.org/schema/aop/spring-aop.xsd
                                    http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/tx 
                                    http://www.springframework.org/schema/tx/spring-tx.xsd
                                    http://www.springframework.org/schema/context/spring-context.xsd">
          
      <!-- 加载jdbcinfo.properties文件 -->
      <context:property-placeholder location="classpath:jdbcinfo.properties"/>
      <!-- dataSource -->
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
          <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
          <property name="DriverClass" value="${jdbc.driverClass}"></property>
          <property name="user" value="${jdbc.user}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      <!-- dao -->
      <bean id="accountdao" class="com.heima.dao.impl.AccountDaoImpl">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      <!-- service -->
      <bean id="accountservice" class="com.heima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountdao"></property>
      </bean>
      
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSource"></property>
      </bean>
      <bean id="proxyaccountservice" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!-- 事务管理器 -->
        <property name="transactionManager" ref="txManager"></property>
        <!-- 要代理的目标类 -->
        <property name="target" ref="accountservice"></property>
       <!--  配置事务详情 
       1.传播行为
       2.隔离级别
       3.是否只读
       4.-Exception 遇到异常回滚
       5.+Exception 遇到异常要提交事务
       -->
        <property name="transactionAttributes">     
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
      </bean>
      
      </beans>
      View Code

      3.基于tx/aop实现方式

    1.配置事务管理器
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"></property>
    </bean>
    2.对事物管理器进行增强
    <tx:advice transaction-manager="txManager" id="myadvice">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    3.将通知与目标类关联
    <aop:config>
        <aop:pointcut expression="execution(* com.heima.service.impl.*.*(..))" id="mypointcut"/>
        <aop:advisor advice-ref="myadvice" pointcut-ref="mypointcut"/>
    </aop:config>
    • 修改applicationContext.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:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop 
                                    http://www.springframework.org/schema/aop/spring-aop.xsd
                                    http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/context/spring-context.xsd
                                    http://www.springframework.org/schema/tx 
                                    http://www.springframework.org/schema/tx/spring-tx.xsd">    
                                    
      <!-- 加载jdbcinfo.properties文件 -->
      <context:property-placeholder location="classpath:jdbcinfo.properties"/>
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
          <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
          <property name="DriverClass" value="${jdbc.driverClass}"></property>
          <property name="user" value="${jdbc.user}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      
      <bean id="accountdao" class="com.heima.dao.impl.AccountDaoImpl">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      
      <bean id="accountservice" class="com.heima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountdao"></property>
      </bean>
      <!-- 配置事务管理器-->
       <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSource"></property>
      </bean>
      <!-- 对事务管理器进行增强 -->
      <tx:advice transaction-manager="txManager" id="myadvice">
          <tx:attributes>
              <tx:method name="transfer" propagation="REQUIRED"/>
          </tx:attributes>
      </tx:advice>
      <!-- 对事件进行切入 -->
      <aop:config>
          <aop:pointcut expression="execution(* com.heima.service.impl.*.*(..))" id="mypointcut"/>
          <aop:advisor advice-ref="myadvice" pointcut-ref="mypointcut"/>
      </aop:config>
      </beans> 
      View Code

      4.基于注解实现

    • 在xml中配置事务管理器
      <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"></property>
      </bean>   
    • 把它交给spring容器中注册驱动便可<tx:annotation-driven transaction-manager="txManager"/>
    • 最后在类或方法上加入注解 @Transactional(propagation=Propagation.REQUIRED) 事务详情放在注解里面配置便可
    • 修改application.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:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                    http://www.springframework.org/schema/beans/spring-beans.xsd
                                    http://www.springframework.org/schema/aop 
                                    http://www.springframework.org/schema/aop/spring-aop.xsd
                                    http://www.springframework.org/schema/context 
                                    http://www.springframework.org/schema/context/spring-context.xsd
                                    http://www.springframework.org/schema/tx 
                                    http://www.springframework.org/schema/tx/spring-tx.xsd">    
                                    
      <!-- 加载jdbcinfo.properties文件 -->
      <context:property-placeholder location="classpath:jdbcinfo.properties"/>
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">   
          <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
          <property name="DriverClass" value="${jdbc.driverClass}"></property>
          <property name="user" value="${jdbc.user}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      
      <bean id="accountdao" class="com.heima.dao.impl.AccountDaoImpl">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      
      <bean id="accountservice" class="com.heima.service.impl.AccountServiceImpl">
          <property name="accountdao" ref="accountdao"></property>
      </bean>
      <!-- 配置事务管理器-->
       <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSource"></property>
      </bean>
      <tx:annotation-driven transaction-manager="txManager"/>
      </beans> 
      View Code

      只要在要使用的类或方法上加上注解便可

    • 或者:



      

     

      

          

      

  • 相关阅读:
    用Java socket (TCP通信模型)实现一个简单的web 服务器
    java.net.BindException: 权限不够
    java 反射机制探究
    java程序执行顺序
    python 安装第三方库,超时报错--Read timed out.
    RTTI和反射
    Ubuntu 16.04
    20160515-hibernate--事务
    Ubuntu 16.04
    python--继承和多态
  • 原文地址:https://www.cnblogs.com/ggr0305/p/6530164.html
Copyright © 2011-2022 走看看