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

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

  • 或者:



  

 

  

      

  

原文地址:https://www.cnblogs.com/ggr0305/p/6530164.html