AOP 应用:事务管理

  两个数据层的类 Dao1 和 Dao2,这里只是用最简单的插入语句来演示。

package com.youka.aop.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class Dao1 {
    
    	
	private JdbcTemplate jdbcTemplate;	
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    
    
		this.jdbcTemplate = jdbcTemplate;
	}
	public int insert(String name, String sex) {
    
    
		String sql = "insert into test1 (name,sex) value (?,?)";
		return jdbcTemplate.update(sql,name,sex);
	}
}
package com.youka.aop.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class Dao2 {
    
    
	private JdbcTemplate jdbcTemplate;
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    
    
		this.jdbcTemplate = jdbcTemplate;
	}
	public int insert(int code) {
    
    
		String sql = "insert into test2 (code) value (?)";
		// 模拟异常
		if (code == 3)
			code = code / 0;
		return jdbcTemplate.update(sql, code);
	}
}

  控制层 Service1 类

package com.youka.aop.service;

import com.youka.aop.dao.Dao1;
import com.youka.aop.dao.Dao2;

public class Service1 {
    
    

	private Dao1 dao1;
	private Dao2 dao2;
	public void setDao1(Dao1 dao1) {
    
    
		this.dao1 = dao1;
	}
	public void setDao2(Dao2 dao2) {
    
    
		this.dao2 = dao2;
	}
	public void insert(String name, String sex, int code) {
    
    
		dao1.insert(name, sex);
		dao2.insert(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: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/context
	                    http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- spring-jdbc -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource1">
		<property name="driverClassName" value="${driver}"></property>
		<property name="url" value="${url}"></property>
		<property name="username" value="${user}"></property>
		<property name="password" value="${password}"></property>
	</bean>	
	<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate1">
		<property name="dataSource" ref="dataSource1"></property>
	</bean>	
	
	<bean class="com.youka.aop.dao.Dao1" id="dao1">
		<property name="jdbcTemplate" ref="jdbcTemplate1"></property>
	</bean>
	<bean class="com.youka.aop.dao.Dao2" id="dao2">
		<property name="jdbcTemplate" ref="jdbcTemplate1"></property>
	</bean>	
	<bean class="com.youka.aop.service.Service1" id="service">
		<property name="dao1" ref="dao1"></property>
		<property name="dao2" ref="dao2"></property>
	</bean>
</beans>

  测试文件

package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.youka.aop.service.Service1;
public class test {
    
    
	public static void main(String[] args) {
    
    
		String             path    = "application.xml";
		ApplicationContext context = new ClassPathXmlApplicationContext(path);
		Service1           service = (Service1) context.getBean("service");		
		service.insert("shiwu", "nan", 3);
	}
}

  如果不进行事务管理,执行完测试类 test 的 main 方法之后,会出现的现象是在 test1·表中添加了一条记录,但是 test2 表中因为发生了异常并没有添加记录。这在实际项目中是不允许出现的,例如,A 从银行 C 给 B 转账 100 元,银行从 A 账号减了 100 元,但是在执行给 B 账号加 100 元的时候出现异常了,最后并没有给 B 账户加上这 100 元,而且也没有返回 A 账号 100 元,这是不可接受的。

AOP 执行事务管理

pom.xml 引入依赖

<!-- AOP 需要的包>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.9.1</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.1</version>
</dependency>

事务管理器

<!-- 事务管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
	<property name="dataSource" ref="dataSource1"></property>
</bean>

增强

  需要用到 tx,需要在根标签处添加命名空间

// 添加 tx 命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
// 在 xsi:schmaLocation 中添加 tx.xsd 的 Location 信息
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
<!-- 增强 -->
<tx:advice transaction-manager="transactionManager">
	<!-- 需要切的连接点 -->
	<tx:attributes>
		<!-- 表示切到以insert开头的方法上,事务处理机制是一个事务 -->
		<tx:method name="insert*" propagation="REQUIRED"></tx:method>
		<tx:method name="update*" propagation="REQUIRED"></tx:method>
		<tx:method name="delete*" propagation="REQUIRED"></tx:method>
	</tx:attributes>
</tx:advice>

AOP

  需要用到 aop,需要在根标签处添加命名空间

// 添加 tx 命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
// 在 xsi:schmaLocation 中添加 tx.xsd 的 Location 信息
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/tx/spring-aop.xsd

  连接点 —— Service1 类的 insert 方法
  切点 —— Service1 包下的所有方法
  切面 —— 切点 + 增强

<!-- 增强 -->
<tx:advice transaction-manager="transactionManager" id="advice1">
	<!-- 需要切的连接点 -->
	<tx:attributes>
		<!-- 表示切到以insert开头的方法上,事务处理机制是一个事务 -->
		<tx:method name="insert*" propagation="REQUIRED"></tx:method>
		<tx:method name="update*" propagation="REQUIRED"></tx:method>
		<tx:method name="delete*" propagation="REQUIRED"></tx:method>
	</tx:attributes>
</tx:advice>
<!-- aop -->
<aop:config>
	<!-- 切点 -->
	<aop:pointcut expression="execution(* com.youka.aop.service.*.*(..))" id="pointCut1"/>
	<!-- 切面 -->
	<aop:advisor advice-ref="advice1" pointcut-ref="ponitCut1"/>
</aop:config>

知识点

<tx:method name="insert*" propagation="REQUIRED"></tx:method>

  propagation 有七个属性值。

属性值 描述
REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED 支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
<aop:pointcut expression="* com.youka.aop.service.*.*(..)" id="pointCut1"/>

  expression 语法:execution(修饰符 返回值 包名.类名/接口名.方法名(参数列表)),* 表示任意值。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40395874/article/details/114411042
今日推荐