Spring框架学习笔记5----事务管理

目录

 

1、什么是事务

2、事务管理介绍

2.1、导入jar包

2.2、三个顶级接口

2.3、PlatformTransactionManager 事务管理器

2.4、TrancationStatus 事务状态

2.5、TransactionDefinition事务详情

3、案例:转账

3.1、搭建环境

3.1.1创建表

3.1.2、导入jar包

3.2、手动管理事务

3.2.1、修改service

3.3、工厂bean生成代理(半自动)

3.3.1、Spring的配置

3.3.2、测试类(使用代理对象)

3.4、AOP配置基于XML【掌握】

3.4.1、配置文件

3.4.2、测试类

3.5、AOP配置基于注解

3.5.1、Spring的配置

3.5.2、实现类中添加注解


1、什么是事务

  • 事务:一组业务操作,要么全部成功,要么全部失败
  • 四大特性:ACID
  1. 原子性:一个事务是一个不可分割单位,要么全发生,要么全不发生
  2. 一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态
  3. 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持久性:持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
  • 隔离问题:
  1. 脏读:一个事务读到另一个事务没有提交的数据
  2. 不可重复读:一个事务读到另一个事务已提交的数据(update)
  3. 幻读:一个事务读到另一个事务已经提交的数据(insert)
  • 隔离级别:
  1. read uncommitted:读未提交,存在3个问题
  2. read committed:读已提交,存在2个问题
  3. repeatable read:可重复读,存在一个问题
  4. serializable:串行化,可以解决三个问题
  • 事务的操作
ABCD一个事务
Connection conn = null;
try{
    //1、获得连接
    conn = 
    //2、开启事务
    conn.setAutoCommit(false);
    A
    B
    C
    D
    //3、提交事务
    conn.commit();
}catch{
    //回滚事务
    conn.rollback();
}
  • mysql事务操作--Savepoint
  •  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();
}catch{
    if(savepoint!=null){//AB没有出错,那么savepoint是有值的
        //CD异常
        //回滚到CD之前
        conn.rollback(savepoint);
        //提交AB
        conn.commit();
    }else{//savepoint为空,说明AB异常
        //回滚AB
        conn.rollback();
    }    
}

2、事务管理介绍

2.1、导入jar包

2.2、三个顶级接口

  • PlatformTransactionManager:平台事务管理器,spring要管理事务,必须使用事务管理器。(进行事务配置时,必须配置事务管理器
  • TransactionDefinition:事务定义(事务详情、事务的属性),spring用于确定事务的具体详情的,例如:隔离级别、是否只读、超时时间等等。(之后进行事务配置时,必须配置详情,spring将配置封装到该对象实例
  • TransactionStatus:事务状态,Spring用于记录当前事务的运行状态。例如:是否有保存点,事务是否已经完成等。(spring底层根据状态进行相应的操作。)

2.3、PlatformTransactionManager 事务管理器

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

  • 常见的事务管理器

1、DataSourceTransactionManager:jdbc开发时事务管理器,采用JDBCTemplate

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

 

  • 接口:PlatformTransactionManager源码详解
package org.springframework.transaction;
public interface PlatformTransactionManager {
    //1、事务管理器,通过”事务详情“,获得”事务状态“,从而管理事务
    TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;
    //2、根据状态提交
    void commit(TransactionStatus var1) throws TransactionException;
    //3、根据状态回滚
    void rollback(TransactionStatus var1) throws TransactionException;
}

2.4、TrancationStatus 事务状态

  • 接口:TransactionStatus源码详解
package org.springframework.transaction;
import java.io.Flushable;
public interface TransactionStatus extends SavepointManager, Flushable {
    //1、是否是新的事务
    boolean isNewTransaction();
    //2、是否有保存点
    boolean hasSavepoint();
    //3、设置回滚
    void setRollbackOnly();
    //4、是否回滚
    boolean isRollbackOnly();
    //5、刷新
    void flush();
    //6、是否完成
    boolean isCompleted();
}

2.5、TransactionDefinition事务详情

  • 接口:TransactionDefinition详解
package org.springframework.transaction;
public interface TransactionDefinition {
    //传播行为
    int PROPAGATION_REQUIRED = 0;//必须:支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将创建一个新的事务
    int PROPAGATION_SUPPORTS = 1;//支持:支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将以非事务执行
    int PROPAGATION_MANDATORY = 2;//强制:支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将抛异常
    int PROPAGATION_REQUIRES_NEW = 3;//必须新的:必创建一个新的事务,A如果有事务,将A的事务挂起,B创建一个新的事务;A如果没有事务,B直接创建一个新的事务
    int PROPAGATION_NOT_SUPPORTED = 4;//不支持:不支持当前事务,总是以非事务执行。如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B直接以非事务执行
    int PROPAGATION_NEVER = 5;//从不:不支持当前事务,如果有的话会抛出异常。如果A有事务,那么B将抛出异常,如果A没有事务,B将以非事务执行
    int PROPAGATION_NESTED = 6;//嵌套:A和B底层采用保存点的机制,形成嵌套事务
    //隔离级别
    int ISOLATION_DEFAULT = -1;默认的,oracle默认为2,mysql默认为4
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;//
    int ISOLATION_REPEATABLE_READ = 4;//
    int ISOLATION_SERIALIZABLE = 8;

    int TIMEOUT_DEFAULT = -1;//默认的超时时间,使用的是数据库底层的超时时间
    //1、传播行为:*******
    int getPropagationBehavior();
    //2、隔离级别
    int getIsolationLevel();
    //3、获得超时时间
    int getTimeout();
    //4、是否只读(一般情况下增删改:读写,查询:只读)
    boolean isReadOnly();
    //5、配置事务详情的名称,一般是方法名称。例如:save
    String getName();
}

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

  • PROPAGATION_REQUIRED :必须,支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将创建一个新的事务【默认值】【掌握】
  • PROPAGATION_SUPPORTS:支持,支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将以非事务执行
  • PROPAGATION_MANDATORY :强制,支持当前事务,A如果有事务,B将使用该事务;A若没有事务,B将抛异常
  • PROPAGATION_REQUIRES_NEW:必须新的,必创建一个新的事务,A如果有事务,将A的事务挂起,B创建一个新的事务;A如果没有事务,B直接创建一个新的事务【掌握】
  • PROPAGATION_NOT_SUPPORTED :不支持,不支持当前事务,总是以非事务执行。如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B直接以非事务执行
  • PROPAGATION_NEVER = 5:从不,不支持当前事务,如果有的话会抛出异常。如果A有事务,那么B将抛出异常,如果A没有事务,B将以非事务执行
  • PROPAGATION_NESTED :嵌套,A和B底层采用保存点的机制,形成嵌套事务【掌握】

3、案例:转账

3.1、搭建环境

3.1.1创建表

create table account(
    id int primary key auto_increment,
    username varchar(50),
    money int
);
insert into account(username,money) values ('jack',1000),('rose',1000);

3.1.2、导入jar包

  • 核心:4+1(core、context、expression、bean +loggin)
  • aop:4(aop联盟、Spring aop、aspectJ规范、spring aspect)
  • 数据库:2(jdbc + tx)
  • 驱动:mysql驱动
  • 连接池:c3p0

3.1.3、Dao层(接口+实现类)

 接口

package tx_dao;
public interface AccountDao {
    public void out(String outer,Integer money);//转账
    public void in(String inner,Integer money);//收款
}

实现类:

package tx_dao_impl;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import tx_dao.AccountDao;

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void out(String outer, Integer money) {
        super.getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer);
    }

    @Override
    public void in(String inner, Integer money) {
        super.getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner);
    }
}

3.1.4、Service层(接口+实现类)

接口:
 

package tx_service;
public interface AccountService {
    //转账
    public void transfer(String outer,String inner,Integer money);
}

实现类:

package tx_service_impl;

import tx_dao.AccountDao;
import tx_service.AccountService;

public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void transfer(String outer, String inner, Integer money) {
        accountDao.out(outer,money);
        accountDao.in(inner,money);
    }
}

3.1.5、spring配置

<?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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    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">

    <!--配置datasource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value = "com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring03"></property>
        <property name="user" value = "root"></property>
        <property name="password" value = "hmx123456"></property>
    </bean>
    <!--配置dao
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void out(String outer, Integer money) {
        super.getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer);
    }

    @Override
    public void in(String inner, Integer money) {
        super.getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner);
    }
    }
    -->
    <bean id="accountDaoId" class="tx_dao_impl.AccountDaoImpl">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>
    <!--配置service
    public class AccountServiceImpl implements AccountService{
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void transfer(String outer, String inner, Integer money) {
        accountDao.out(outer,money);
        accountDao.in(inner,money);
    }
    }
    -->
    <bean id="accountServiceId" class="tx_service_impl.AccountServiceImpl">
        <property name="accountDao" ref = "accountDaoId"></property>
    </bean>    
</beans>

3.1.6、测试类

package tx_test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tx_service.AccountService;

public class TestApp {
    @Test
    public void demo01(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = applicationContext.getBean("accountServiceId",AccountService.class);
        accountService.transfer("jack","rose",20);
    }
}

3.2、手动管理事务

  • spring底层使用TransactionTemplate事务模板进行操作
  • 操作
  1. service需要获得TransactionTemplate
  2. spring配置模版,并注入给service
  3. 模版需要注入事务管理器
  4. 配置事务管理器

3.2.1、修改service

package tx2_service_impl;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import tx2_dao.AccountDao;
import tx2_service.AccountService;

public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    //需要spring注入模版
    private TransactionTemplate transactionTemplate;//事务模版

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void transfer(String outer, String inner, Integer money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outer(outer,money);
                //模拟一个异常
                int i = 1/0;
                accountDao.inner(inner,money);
            }

        });
    }
}

 

3.2.2、修改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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    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">

    <!--1、配置datasource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value = "com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring03"></property>
        <property name="user" value = "root"></property>
        <property name="password" value = "hmx123456"></property>
    </bean>
    <!--2、dao-->
    <bean id="accountDao" class="tx2_dao_impl.AccountDaoImpl">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>
    <!--3、service-->
    <bean id="accountService" class="tx2_service_impl.AccountServiceImpl">
        <property name="accountDao" ref = "accountDao"></property>
        <property name="transactionTemplate" ref = "transactionTemplate"></property>
    </bean>

    <!--4、创建模版-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref = "txManager"></property>

    </bean>
    <!--5、配置事务管理器:管理器需要事务,事务从Connection获得,连接从连接池DataSource获得-->
    <bean id="txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>

</beans>

3.3、工厂bean生成代理(半自动)

  • spring提供 管理事务的代理工厂 bean TransactionProxyFactoryBean
    1、getBean()获得代理对象
    2、在spring中配置一个代理

3.3.1、Spring的配置

<?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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    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">

    <!--1、配置datasource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value = "com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring03"></property>
        <property name="user" value = "root"></property>
        <property name="password" value = "hmx123456"></property>
    </bean>
    <!--2、配置dao-->
    <bean id = "accountDaoId" class="tx3_dao_impl.AccountDaoImpl">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>
    <!--3、配置service-->
    <bean id = "accountServiceId" class="tx3_service_impl.AccountServiceImpl">
        <property name="accountDao" ref = "accountDaoId"></property>
    </bean>
    <!--4、生成代理
    1:接口:proxyInterfaces-目标类接口
    2:目标类:target-目标类的引用
    3:事务管理器:transactionManager
    4:事务属性:transactionAttributes
        prop.key:确定哪些方法使用当前的事务配置
        prop.text:用于配置事务详情
            格式:PROPAGATION(传播行为)、ISOLATTON(隔离级别)、readOnly(是否只读)、-Excepion(异常回滚:发生异常回滚)、+Exception(异常提交:发生异常仍然要提交)
            例如:<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认的传播行为和默认的隔离级别
                 <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop>只读
    -->
    <bean id = "proxyAccountServiceId" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="proxyInterfaces" value = "tx3_service.AccountService"></property>
        <property name="target" ref = "accountServiceId"></property>
        <property name="transactionManager" ref = "txManager"></property>
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop>
            </props>
        </property>
    </bean>
    <!--5、配置事务管理器-->
    <bean id = "txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

3.3.2、测试类(使用代理对象)

package tx3_test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tx3_service.AccountService;

public class TestApp {
    @Test
    public void demo01(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = applicationContext.getBean("proxyAccountServiceId",AccountService.class);
        accountService.transfer("rose","jack",20);
    }
}

3.4、AOP配置基于XML【掌握】

  • 在spring xml 配置 aop自动生成代理,进行事务管理
    1、配置管理器
    2、配置事务详情
    3、配置aop

3.4.1、配置文件

<?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: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.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">

    <!--1、配置datasource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value = "com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring03"></property>
        <property name="user" value = "root"></property>
        <property name="password" value = "hmx123456"></property>
    </bean>
    <!--2、配置dao-->
    <bean id = "accountDaoId" class="tx4_dao_impl.AccountDaoImpl">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>
    <!--3、配置service-->
    <bean id = "accountServiceId" class="tx4_service_impl.AccountServiceImpl">
        <property name="accountDao" ref = "accountDaoId"></property>
    </bean>
    <!--4、事务管理-->
    <!--4.1 事务管理器
    -->
    <bean id = "txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--4.2 事务详情:(事务通知):在aop筛选的基础上,对ABC三个确定使用什么样的事务。例如:A和C是读写的,B是只读的
    <tx:attributes>:用于配置事务的详情(属性)
        <tx:method name=""/>:详情的具体配置
            propagation 传播行为
            isolation:隔离级别
    -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" />
        </tx:attributes>
    </tx:advice>
    <!--4.3 AOP编程,目标类有ABCD4个方法(即四个连接点),切入点表达式:确定需要增强的连接点,从而获得切入点:-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* tx4_service..*.*(..))"></aop:advisor>
    </aop:config>
</beans

3.4.2、测试类

package tx4_test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tx4_service.AccountService;

public class TestApp {
    @Test
    public void demo(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = (AccountService)applicationContext.getBean("accountServiceId");
        accountService.transfer("jack","rose",100);
    }
}

3.5、AOP配置基于注解

  • 配置事务管理器,将事务管理器交与Spring
  • 在目标类或者目标方法添加注解 @Transactional

3.5.1、Spring的配置

<?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: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.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">

    <!--1、配置datasource-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value = "com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value = "jdbc:mysql://localhost:3306/spring03"></property>
        <property name="user" value = "root"></property>
        <property name="password" value = "hmx123456"></property>
    </bean>
    <bean id = "accountDao" class="tx5_dao_impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id = "accountService" class="tx5_service_impl.AccountServiceImpl">
        <property name="accountDao" ref = "accountDao"></property>
    </bean>
    <!--配置事务管理
    1、事务管理器
    2、将事务管理器交予spring
    -->
    <bean id = "txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref = "dataSource"></property>
    </bean>
    <!--将管理器交与spring-->
    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
</beans>

3.5.2、实现类中添加注解

package tx5_service_impl;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tx5_dao.AccountDao;
import tx5_service.AccountService;
//@Transactional:如果给类加注解,那么就是对类,该类中的所有方法都适用
public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED,isolation = Isolation.DEFAULT)
    public void transfer(String outer, String inner, Integer money) {
        accountDao.outer(outer,money);
        accountDao.inner(inner,money);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值