spring事务管理之通过xml配置aop事务

案例名称:myspring_day03_tx

一句话说明:本文讲解如何在spring中通过xml配置方式,以aop思想为核心,来配置事务管理。

详细说明:此案例实现转账业务,service(业务实现类)在调用dao(数据库操作类)实现业务时,需要为某些方法添加事务管理,以保证数据的正确。此案例利用aop思想,通过xml配置的方式,将通知(即事务管理,由事务核心管理器提供,见配置文件第6步)织入目标(MoneyService类)的切点(transf方法),以达到增强切点(transf方法)的作用(为切点提供了事务管理)。

步骤:

1.准备dao接口及其实现类,依赖DataSource(继承JdbcDaoSupport,获得JdbcTemplate,使用其update执行sql语句)

package dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
/**
 * dao类,提供操作数据库的方法,供service使用
 * @author 74047
 */
public class MoneyDao extends JdbcDaoSupport implements dao {

	public void addMoney(double money, Integer id) {
		// 通过父类JdbcDaoSupport的getJdbcTemplate方法获得JdbcTemplate(jdbc模板),
		//但是注意继承之后,会导致此类依赖dataSource,记得注入
		getJdbcTemplate().update("update t_account set money=money+? where id = ?", money, id);
	}

	public void reduceMoney(double money, Integer id) {
		getJdbcTemplate().update("update t_account set money=money-? where id = ?", money, id);
	}
}

 

2.准备service接口及其实现类,依赖dao实现类(调用dao实现类的方法完成业务)

 

package service;

import dao.MoneyDao;
/**
 * service类,通过调用dao的方法完成转账业务逻辑
 * 此类是事务aop增强的目标类
 * @author 74047
 *
 */
public class MoneyService implements service {
	//需要依赖dao
	private MoneyDao dao;
	/**
	 * 此为转账业务,也是事务aop增强的切点
	 */
	public void transf(Integer from, Integer to, Integer money) {

		dao.reduceMoney(money, from);
		//故意制造异常,测试事务是否生效
//		int i = 1 / 0;
		dao.addMoney(money, to);
	}

	public void setDao(MoneyDao dao) {
		this.dao = dao;
	}
}

 

3.配置文件(放在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">
	<!-- 1.配置连接池 -->
	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="jdbcUrl" value="jdbc:mysql:///springdb"></property>
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="user" value="root"></property>
		<property name="password" value=""></property>
	</bean>
	
	<!-- 2.配置dao实现类,依赖连接池(1) -->
	<bean name="moneyDaoImpl" class="dao.MoneyDao">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 3.配置service实现类,依赖dao实现类(2) -->
	<bean name="moneyServiceImpl" class="service.MoneyService">
		<property name="dao" ref="moneyDaoImpl"></property>
	</bean>
	
	<!-- 4.配置事务核心管理器,依赖连接池(1) -->
	<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 5.配置事务模板,依赖事务核心管理器(4) -->
	<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
	</bean>
	
	<!-- 6.配置事务通知,依赖事务核心管理器(4) -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transf" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 7.配置织入 -->
	<aop:config>
		<aop:pointcut expression="execution(* service.*Service.*(..))" id="txpc"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txpc"/>
	</aop:config>
	
	
</beans>

4.测试

package demo;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import service.service;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
	// 用不了@Resource的话,可能需要导包com.springsource.javax.annotation-1.0.0.jar
	@Resource(name = "moneyServiceImpl")
	// 这里需要类型是接口类型,用实现类的类型会报下面的错
	/*
	 * org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean
	 * named 'moneyServiceImpl' must be of type [service.MoneyService], but was
	 * actually of type [com.sun.proxy.$Proxy13]
	 */
   // 拓展阅读:https://stackoverflow.com/questions/14509142/beannotofrequiredtypeexception
	private service ms;

	@Test
	public void fun1() {
		ms.transf(1, 2, 100);
	}
}

 

第一次使用spring的过程中遇到很多坑,挑选典型的若干错误如下:

 

1.准备dao接口及其实现类时,sql语句错误,且此类要实现接口

2.准备service接口及其实现类时,要为依赖的dao添加set 方法,且此类要实现接口

3.配置文件中,配置service实现类时,属性是引用类型时要用ref注入

4.配置文件中,配置事务模板时,要加id和transaction-manager属性

5.配置文件中,配置事务模板时,切点表达式的第一个*(表示返回值任意)之后要带一个空格execution(* service.*Service.*(..)) 

6.测试类Demo里获取service实现类进行事务操作时,service实现类的类型需要是接口类型(父类引用),且通过容器获得实现类对象时,需要使用@Resource(name="moneyServiceImpl")注解,如果不能使用此注解,则需要导入com.springsource.javax.annotation-1.0.0.jar包

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值