Spring中使用声明式事务管理

创建业务层代码

package com.itheima.demo2;

public class AccountServiceImpl implements AccountService {
	
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	
	/**
	 * 转账的方法
	 */
	public void pay(final String out, final String in, final double money) {
		// 先扣钱
		accountDao.outMoney(out, money);
		// 模拟异常
		int a = 10/0;
		// 加钱
		accountDao.inMoney(in, money);
	}
}

创建Dao层代码

package com.itheima.demo2;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
// JdbcDaoSupport中已经通过setDataSource方法定义了常量的JdbcTemplate对象,所有注入dataSource就行了
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
	
	/**
	 * 扣钱
	 */
	public void outMoney(String out, double money) {
		this.getJdbcTemplate().update("update t_account set money = money - ? where name = ?", money,out);
	}
	
	/**
	 * 加钱
	 */
	public void inMoney(String in, double money) {
		this.getJdbcTemplate().update("update t_account set money = money + ? where name = ?", money,in);
	}

}

基于XML的声明式事务

创建配置文件,在src目录下创建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">
    <!-- 配置C3P0的连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!-- 配置平台事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 平台事务管理器需要配置数据源才能够管理事务 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 声明式事务(采用XML配置文件的方式) -->
	<!-- 先配置通知 -->
	<tx:advice id="myAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 给方法设置数据库属性(隔离级别,传播行为) -->
            <!--
				name		:绑定事务的方法名,可以使用通配符,可以配置多个。
				propagation	:传播行为	
				isolation	:隔离级别;有以下五种:
							ISOLATION_DEFAULT(默认值,采用数据库的隔离级别)
							ISOLATION_READ_UNCOMMITTED: 读未提交
							ISOLATION_READ_COMMITTED: 读已提交(可避免脏读)
							ISOLATION_REPEATABLE_READ: 可重复读(可避免脏读和不可重复读)
							ISOLATION_SERIALIZABLE: 串行化(可避免脏读,不可重复读,幻读)
				read-only	:是否只读
				timeout		:超时信息
				rollback-for:发生哪些异常回滚.
				no-rollback-for:发生哪些异常不回滚.
			 -->
			<tx:method name="pay" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
    <!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知aop:advisor -->
	<aop:config>
		<!-- aop:advisor,是Spring框架提供的通知 -->
		<aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.itheima.demo2.AccountServiceImpl.pay(..))"/>
	</aop:config>
    <!-- 配置业务层和持久层 -->
	<bean id="accountService" class="com.itheima.demo2.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<bean id="accountDao" class="com.itheima.demo2.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
</beans>

基于注解的声明式事务

创建配置文件,在src目录下创建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">
	
	<!-- 配置C3P0的连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"/>
		<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
		<property name="user" value="root"/>
		<property name="password" value="root"/>
	</bean>
	
	<!-- 配置平台事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 开启事务的注解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	
	<!-- 配置业务层和持久层 -->
	<bean id="accountService" class="com.itheima.demo3.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<bean id="accountDao" class="com.itheima.demo3.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
</beans>

在业务层上添加一个注解:@Transactional:

package com.itheima.demo3;

import org.springframework.transaction.annotation.Transactional;

/**
 * Transactional类上添加了注解,类中的所有的方法全部都有事务
 * @author Administrator
 */
public class AccountServiceImpl implements AccountService {
	
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	
	/**
	 * 转账的方法
	 */
	@Transactional
	public void pay(final String out, final String in, final double money) {
		// 先扣钱
		accountDao.outMoney(out, money);
		// 模拟异常
		int a = 10/0;
		// 加钱
		accountDao.inMoney(in, money);
	}
	
}

事务的传播行为

  1. 举例说明什么是事务的传播行为:
    比如说一个类中有两个方法A和B方法,这两个方法通过AOP技术都增强提交事务的功能
public class Hello{
    public void A(){
        张三用户减100元操作;
        // 调用B方法
        this.B();
    }
    public void B(){
        李四用户加100元操作
    }
}

事务的传播行为就是来解决这种事务(A)调用事务(B)时,被调用事务方法(B)如何进行事务管理的问题

  1. 共有七种解决方案(即7种传播行为)
    <1> PROPAGATION_REQUIRED(默认值): A中有事务,使用A中的事务.如果没有,B就会开启一个新的事务,将A包含进来.(保证A,B在同一个事务中),默认值!!
    <2> PROPAGATION_SUPPORTS: A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.
    <3> PROPAGATION_MANDATORY: A中有事务,使用A中的事务.如果A没有事务.抛出异常.
    <4> PROPAGATION_REQUIRES_NEW: A中有事务,将A中的事务挂起.B创建一个新的事务.(保证A,B没有在一个事务中)
    <5> PROPAGATION_NOT_SUPPORTED: A中有事务,将A中的事务挂起.
    <6> PROPAGATION_NEVER: A中有事务,抛出异常.
    <7> PROPAGATION_NESTED: 嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)

声明:
有一些博文是看的黑马程序员视频,然后跟着老师做的笔记
Spring是跟子路老师学的
特此感谢,写这些文章的目的是为了自己方便查阅

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值