Spring事务管理——AOP配置

说明

平时学习Spring很少用到AOP这个功能,不过这个功能对Spring事务管理有一定的作用。发现真正在用的时候自己配环境的情况特别少,都是在别人配好环境的情况下就开始用了。所以更加要记录一下配置环境的过程啊。这里用一个转账实例来说明。

Spring事务管理

事务管理一般涉及到三个顶级接口,分别是PlatformTransactionManager(事务管理器),TransactionDefinition(事务详情),TransactionStatus(事务状态)。进行事务配置时,必须要配置事务管理器和事务详情。而事务状态是Spring底层用来进行相应操作的。

事务

开始之前说一下事务吧。这里有一点简单的介绍,可以看一下,这里要再说一下。事务状态和事务详情就不说了,可以查一下。这里主要说一下传播行为,比较常用的记录一下,不常用的不说了。
传播行为主要是指两个业务之间如何共享事务
例如转账的时候,先要从一个账户出账,然后另一个账户入账,这就可以看成是两个业务。传播行为常用的主要有下面几种:

required:必须
支持当前事务,A如果有事务,B将使用该事务,如果A没有事务,B将创建一个新的事务
supports:支持
支持当前事务,A如果有事务,B将使用该事务,如果A没有事务,B将以非事务执行
requires_new:必须新的
如果A有事务,将A的事务挂起,B创建一个新的事务,如果A没有事务,B创建一个新事务

事务管理器

我们比较常用的事务管理器一般有两种,分别是DataSourceTransactionManager和HibernateTransactionManager。

  • DataSourceTransactionManager:jdbc开发时的事务管理器,采用jdbcTemplate
  • HibernateTransactionManager:hibernate开发时用的事务管理器

这里用DataSourceTransactionManager来说明

准备工作

下面是一些准备工作,我们需要数据库中的数据,所以这里新建一个数据库

create database 数据库名;
use 数据库名;
create table account(
	id int primary key auto_increment,
	username varchar(50),
	money int(20)
	);
	insert into account values(null,"jack",10000);
	insert into account values(null,"rose",10000);

在这里插入图片描述
除了这个之外,我们还要新建一个项目,待会方便直接使用
jar包
在这里插入图片描述
目录
在这里插入图片描述
都是比较基础的代码,直接贴出来就好。

interface AccountDao

package com.shanmu.dao;

public interface AccountDao {

	public void out(String outer,Integer money);
	public void in(String inner,Integer money);
}

class AccountDaoImpl

package com.shanmu.daoimpl;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.shanmu.dao.AccountDao;

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{

	@Override
	public void out(String outer, Integer money) {
		this.getJdbcTemplate().update("update account set money = money -? where username = ?",money,outer);
		
	}

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

interface AccountService

package com.shanmu.service;

public interface AccountService {

	/**
	 * 转账
	 * @param outer
	 * @param inner
	 * @param money
	 */
	public void transfer(String outer,String inner,Integer money);
}

class AccountServiceImpl

package com.shanmu.serviceimpl;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.shanmu.dao.AccountDao;
import com.shanmu.service.AccountService;

public class AccountServiceImpl implements AccountService {

	//由Spring注入
	private AccountDao accountDao;

	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	@Override
	//这里是转账的方法,调用dao
	public void transfer(String outer, String inner, Integer money) {
		accountDao.out(outer, money);
		/*
		这里是测试事务的语句,当int i=1/0没有注释的时候会产生异常,如果没进行事务管理,
		则只会出账,不会进账,总钱数少了1000,如果进行了事务管理,则会回滚,不会提交,
		这样原本的账户不会发生变化。
		*/
		//int i=1/0;
		accountDao.in(inner, money);
	}

}

class TestApp

package com.shanmu;

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

import com.shanmu.service.AccountService;

public class TestApp {

	@Test
	public void demo01(){
		String xmlPath="applicationContext.xml";
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
		AccountService accountService=(AccountService)applicationContext.getBean("accountService");
		accountService.transfer("jack", "rose", 1000);
	}
}

这里的xml文件还没有给出,下面主要来看怎么加入事务了。

AOP配置事务——基于xml

指的是在Spring的xml文件中进行配置aop,自动生成代理,从而进行事务的管理,步骤如下:

  1. 配置事务管理器
  2. 配置事务详情
  3. 配置AOP

看一下配置文件(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/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">
			  <!--
			   xmlns:tx="http://www.springframework.org/schema/tx"
			   xsi:schemaLocation="http://www.springframework.org/schema/tx
			  									   http://www.springframework.org/schema/tx/spring-tx.xsd"
			  是配置事务详情要用到的
			  -->  									   
			  <!-- 1 dataSource -->
			  <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
			  		<property name="driverClass"  value="com.mysql.jdbc.Driver"></property>
			  		<property name="jdbcUrl"  value="jdbc:mysql://localhost:3306/数据库名"></property>
			  		<property name="user"  value="root"></property>
			  		<property name="password"  value="密码"></property>
			  </bean>
			  <!-- 2 dao -->
			  <bean name="accountDao" class="com.shanmu.daoimpl.AccountDaoImpl">
			  		<property name="dataSource" ref="dataSource"></property>
			  </bean>
			  <!-- 3 service -->
			  <bean name="accountService"  class="com.shanmu.serviceimpl.AccountServiceImpl">
			  		<property name="accountDao"  ref="accountDao"></property>
			  </bean>
			  <!-- 4事务管理 -->
			  <!-- 4.1 事务管理器 -->
			  <bean name="txManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			  		<property name="dataSource"  ref="dataSource"></property>
			  </bean>
			  <!-- 4.2 事务详情(事务通知),在aop筛选基础上,对ABC三个确定使用什么样的事务。
			  		<tx:attributes>用于配置事务详情(事务属性)
			  		<tx:method name=""/>详情具体配置
			  				propagation 传播行为
			  				isolation  隔离级别
			   -->
			   <tx:advice id="txAdvice" transaction-manager="txManager">
			   		<tx:attributes>
			   				<!-- 这里传播行为默认为required -->
			   				<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
			   		</tx:attributes>
			   </tx:advice>
			  <!-- 4.3 AOP编程,目标类有ABCD(4个连接点),切入点表达式 确定增强的连接器,从而获得切入点:ABC -->
			  <aop:config>
			  		<aop:advisor advice-ref="txAdvice"  pointcut="execution(* com.shanmu.serviceimpl.*.*(..))"/>
			  </aop:config>

运行结果
在这里插入图片描述
看一下数据库
在这里插入图片描述

AOP配置事务——基于注解

步骤是:

  1. 配置事务管理器,并将事务管理器交于Spring
  2. 在目标类或目标方法中添加注释即可@Transactional

所以,首先在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/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 name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
			  		<property name="driverClass"  value="com.mysql.jdbc.Driver"></property>
			  		<property name="jdbcUrl"  value="jdbc:mysql://localhost:3306/数据库名"></property>
			  		<property name="user"  value="root"></property>
			  		<property name="password"  value="root"></property>
			  </bean>
			  <!-- 2 dao -->
			  <bean name="accountDao" class="com.shanmu.daoimpl.AccountDaoImpl">
			  		<property name="dataSource" ref="dataSource"></property>
			  </bean>
			  <!-- 3 service -->
			  <bean name="accountService"  class="com.shanmu.serviceimpl.AccountServiceImpl">
			  		<property name="accountDao"  ref="accountDao"></property>
			  		<!-- <property name="transactionTemplate"  ref="transactionTemplate"></property> -->
			  </bean>
			  
			   <!-- 4 事务管理 -->
			  <!-- 4.1 事务管理器 -->
			  <bean name="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			  		<property name="dataSource" ref="dataSource"></property>
			  </bean>
			  <!-- 4.2 将管理器交于spring
			  			*  transaction-manager 配置事务管理器
			  			*  proxy-target-class
			  						默认是false
			  						若为true,底层强制使用cglib代理
			   -->
			  <tx:annotation-driven transaction-manager="txManager" />

然后在transfer方法上加上注解

package com.shanmu.serviceimpl;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.shanmu.dao.AccountDao;
import com.shanmu.service.AccountService;

public class AccountServiceImpl implements AccountService {

	private AccountDao accountDao;

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

	@Override
	@Transactional
	//@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
	//给类加上该注解,则该类中所有方法执行事务,给方法上加注解,则该方法执行事务
	public void transfer(String outer, String inner, Integer money) {
		accountDao.out(outer, money);
		/*
		这里是测试事务的语句,当int i=1/0没有注释的时候会产生异常,如果没进行事务管理,
		则只会出账,不会进账,总钱数少了1000,如果进行了事务管理,则会回滚,不会提交,
		这样原本的账户不会发生变化。
		*/
		//int i=1/0;
		accountDao.in(inner, money);
	}
}
```java
这里会发现没有配事务详情,其实@Transactional注解可以写成下面的形式,这样就可以在括号中配置事务详情
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191116202146442.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhbnNtdQ==,size_16,color_FFFFFF,t_70)
**结果**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191116202435116.png)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,可以使用Spring AOP来进行事务管理。其中,事务管理器是一个重要的组件。事务管理器负责管理事务的开始、提交和回滚等操作。在Spring中,常用的事务管理器是DataSourceTransactionManager。这个事务管理器是基于JDBC的事务实现的,适用于持久层采用JDBC相关技术的情况,比如Mybatis。\[1\]\[2\] 在Spring AOP事务管理中,有两个关键的角色:事务管理员和事务协调员。事务管理员通常指的是业务层开启事务的方法,而事务协调员通常指的是数据层方法或者业务层方法。事务管理员负责发起事务,而事务协调员负责加入事务。通过这种方式,可以实现对事务管理和控制。\[3\] 总结起来,Spring AOP事务管理是通过事务管理器来管理事务的开始、提交和回滚等操作。在整合Mybatis时,可以使用DataSourceTransactionManager作为事务管理器。同时,通过事务管理员和事务协调员的配合,可以实现对事务管理和控制。 #### 引用[.reference_title] - *1* [Spring-AOP事务管理](https://blog.csdn.net/qq_53098203/article/details/129532966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spring基础3——AOP事务管理](https://blog.csdn.net/qq_40991313/article/details/126339270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值