Spring的事务管理

Spring的事务管理

1.事务的概念及特性
1. 事务:指的是逻辑上一组操作,组成这个事务的各个执行单元,要么一起成功,要么一起失败!
2. 事务的特性
	原子性:组成这个事务的各个执行单元 不可再分割
	一致性:
    隔离性:
	持久性
2.Spring事务管理的相关的类和API
1. PlatformTransactionManager接口 -- 平台事务管理器.(真正管理事务的类)。该接口有具体的实现类,根据不同的持久层框架,需要选择不同的实现类!
2. TransactionDefinition接口	  -- 事务定义信息.(事务的隔离级别,传播行为,超时,只读)
3. TransactionStatus接口	  -- 事务的状态

4. 总结:上述对象之间的关系:平台事务管理器真正管理事务对象.根据事务定义的信息TransactionDefinition 进行事务管理,在管理事务中产生一些状态.将状态记录到TransactionStatus中

5. PlatformTransactionManager接口中实现类和常用的方法
	1. 接口的实现类
		* 如果使用的Spring的JDBC模板或者MyBatis框架,需要选择DataSourceTransactionManager实现类
		* 如果使用的是Hibernate的框架,需要选择HibernateTransactionManager实现类
	
	2. 该接口的常用方法
		* void commit(TransactionStatus status) 
		* TransactionStatus getTransaction(TransactionDefinition definition) 
		* void rollback(TransactionStatus status) 
 	
6. 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 
 		
	2. 事务的传播行为常量(不用设置,使用默认值)
		* 先解释什么是事务的传播行为:解决的是业务层之间的方法调用!!
		
		* PROPAGATION_REQUIRED(默认值)	-- A中有事务,使用A中的事务.如果没有,B就会开启一个新的事务,将A包含进来.(保证A,B在同一个事务中),默认值!!
		* PROPAGATION_SUPPORTS			-- A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.
		* PROPAGATION_MANDATORY			-- A中有事务,使用A中的事务.如果A没有事务.抛出异常.
		
		* PROPAGATION_REQUIRES_NEW(记)-- A中有事务,将A中的事务挂起.B创建一个新的事务.(保证A,B没有在一个事务中)
		* PROPAGATION_NOT_SUPPORTED		-- A中有事务,将A中的事务挂起.
		* PROPAGATION_NEVER 			-- A中有事务,抛出异常.
		
		* PROPAGATION_NESTED(记)		-- 嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)
3.Spring事务模拟专项业务
1.创建项目,导入jar包
  普通项目中
  	* IOC的6个包
		com.springsource.org.apache.commons.logging-1.1.1.jar
		com.springsource.org.apache.log4j-1.2.15.jar
		spring-beans-5.0.2.RELEASE.jar
		spring-context-5.0.2.RELEASE.jar
		spring-core-5.0.2.RELEASE.jar
		spring-expression-5.0.2.RELEASE.jar
	* AOP的4个包
		 spring-aop-5.0.2.RELEASE.jar
	         com.springsource.org.aopalliance-1.0.0.jar
		 com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
		 spring-aspects-5.0.2.RELEASE.jar
	* C3P0的1个包
		com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
	* MySQL的驱动包
		mysql-connector-java-5.1.7-bin.jar
	* JDBC模板2个包
		 spring-jdbc-5.0.2.RELEASE.jar
		 spring-tx-5.0.2.RELEASE.jar  事务
	* 整合JUnit测试包
		 spring-test-5.0.2.RELEASE.jar
   Maven项目中
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        
          <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    
2.创建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: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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
        <!--开启组件扫描-->
    <context:component-scan base-package="org.best"/>
    <!--配置C3P0数据源-->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123"></property>
    </bean>
    <!--将数据源注入到JDBCTemplate中-->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>
        </beans>
        
3.创建对应的包和类

Service接口

package org.best.service;
public interface AccountService {
    /**
     *
     * @param sendName 转账人姓名
     * @param recieveName 收款人姓名
     * @param money  金额
     */
    void accounts(String sendName,String recieveName,Double money);
}

Service实现类

package org.best.service;

import org.best.dao.AccountDao;
import org.best.dao.AccountDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    //注入Dao
    @Autowired
    @Qualifier("accountDao")
  private AccountDaoImpl accountDao;

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

    public void accounts(String sendName, String recieveName, Double money) {
        accountDao.cutMoney(sendName,money);
        accountDao.addMoney(recieveName,money);
    }
}

Dao接口

package org.best.dao;

public interface AccountDao {
    void addMoney(String name,Double money);
    void cutMoney(String name,Double money);
}

Dao实现类

package org.best.dao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl  implements AccountDao {
    //注入jdbcTemplate
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    public void addMoney(String name, Double money) {
   jdbcTemplate.update("update account set money=money+? where name =?",money,name);
    }

    public void cutMoney(String name, Double money) {
        jdbcTemplate.update("update account set money=money-? where name =?",money,name);
    }
}

4.测试

 @org.junit.Test
    public void Test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = context.getBean("accountService", AccountService.class);
        accountService.accounts("ls","yyp",1500.0);
    }
 
 这样来看,转账事务是没有问题,但是当遇到异常就会造成不可挽回的损失,那么如何解决呢?
  解决方式1.配置文件中加入
    <!--配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="manager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--配置事务增强-->
   <tx:advice id="interceptor" transaction-manager="manager">
       <tx:attributes>
           <!--增删改方法这样配置-->
           <tx:method name="account*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
           <!--查询-->
           <tx:method name="find*" isolation="DEFAULT" read-only="true" propagation="SUPPORTS"/>
       </tx:attributes>
   </tx:advice>


    <!--配置AOP切面产生代理-->
<aop:config>
    <aop:advisor advice-ref="interceptor" pointcut="execution(public * org.best.service.AccountService.accounts(..))"/>
</aop:config>

解决方式2:配置文件加注解

配置文件中加入
   <!--配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="manager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--开启注解事务-->
    <tx:annotation-driven transaction-manager="manager"></tx:annotation-driven>
  
  在所需要类或方法上加@Transactional注解
  加在类上表示类中的所有方法都有了事务
  加在方法上表示表示某个特定方法有了事务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值