Spring 学习笔记《AOP配置事务》

4 篇文章 0 订阅
3 篇文章 0 订阅

简介

今天面试被问到Spring事务的几种配置方法。主流的就是AOP注解,非主流的忽略。
虽然学过AOP,可我一直都是用注解。哑口无言状态。。。233333
大部分时间我接触的事务处理都是用注解,简单方便。但注解必须添加在目标方法上,如果手上没有源码就呵呵了。
通过配置切面的方式开启事务,可以为特定的包、特定前缀的方法,批量添加事务控制。
为了方便测试,我集成了MybatisPlus

依赖

/项目/pom.xml

 		<dependency>
			<groupId>aopalliance</groupId>
			<artifactId>aopalliance</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
		    <groupId>aspectj</groupId>
		    <artifactId>aspectjrt</artifactId>
		    <version>1.5.4</version>
		</dependency>
		<!-- 如果添加了 spring-aspects 此项可省 -->
	    <dependency>
	      <groupId>org.aspectj</groupId>
	      <artifactId>aspectjweaver</artifactId>
	      <version>1.8.9</version>
	      <scope>compile</scope>
	    </dependency>

事务配置

注意

  • tx:advice 配置的事务,默认是触发RuntimeException时回滚。
  • 如果想手动指定触发回滚的异常,看下面 add* 的配置。(似曾相识吧)
    /项目/src/main/resources/applicationContext.xml
	...
	<!-- =========================== 事务 =========================== -->
	<!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean> 
    
	<!-- 配置事务的传播特性 -->  
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes> 
			<!-- 写操作: 增、删、改 --> 
			<tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="upd*" propagation="REQUIRED" />
			<!-- 只读事务:查 --> 
			<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	<!-- 配置需要事务的方法 (切点) -->  
	<aop:config>  
		<aop:pointcut id="txPointcut" expression="execution(* com.jerry.springmvc.service..*.*(..))" />  
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>  
	</aop:config>

服务层(事务就在这干活)

/项目/src/main/java/com/jerry/springmvc/service/impl/PoemService.java
注意这里抛异常用的是RuntimeException

package com.jerry.springmvc.service.impl;

import java.io.Serializable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jerry.springmvc.entity.Poem;
import com.jerry.springmvc.mapper.PoemMapper;
import com.jerry.springmvc.service.IPoemService;

/**
 *  服务实现类
 * @author jerryjin
 * @since 2019-06-19
 */
@Service
public class PoemService extends ServiceImpl<PoemMapper, Poem> implements IPoemService {
	
	@Override
	public String updTransactionTest(Serializable id) throws Exception {
		
		// 首次查询
		Poem poem1 = selectById(id);
		System.out.println("修改前:" + poem1);
		
		// 修改作者名为 666 后更新数据库
		poem1.setAuthor("666");
		updateById(poem1);
		Poem poem2 = selectById(id);
		System.out.println("修改后:" + poem2);
		
		// 最后抛出异常,触发回滚
		throw new RuntimeException("改作者名称是盗版行为");
	}
}

控制器

/项目/src/main/java/com/jerry/springmvc/controller/indexController.java

package com.jerry.springmvc.controller;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jerry.springmvc.entity.Poem;
import com.jerry.springmvc.service.IPoemService;

@Controller
@Scope("prototype")
public class indexController extends BaseController {
	
	@Resource
	private IPoemService poemService;
	
	@RequestMapping(value="/xmltx/{id}", produces={"application/json; charset=UTF-8"})
	@ResponseBody
	public Map<String, Object> updTransactionTest(@PathVariable Long id) {
		
		Map<String , Object> map = new HashMap<String ,Object>();
		try {
			poemService.updTransactionTest(id);
		} catch (Exception e) {
			map.put("exception", e.getMessage());
		}
		
		System.out.println("回滚后:" + poemService.selectById(id));
		
		map.put("pome", poemService.selectById(id));
		
		return map;
	}
	
}

访问 http://127.0.0.1/xmltx/1
控制台输出如下,回滚成功。

修改前:{"author":"笑虾","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}
修改后:{"author":"666","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}
回滚后:{"author":"笑虾","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}

如果我不抛出异常则,作者被改成 666

修改前:{"author":"笑虾","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}
修改后:{"author":"666","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}
回滚后:{"author":"666","content":"<p>多情黯叹痴情癫,痴情苦笑多情难。</p><p>相思自古无良药,从来独步赴黄泉。</p","id":1,"title":"痴情癫"}

参考资料

Spring 事务学习笔记
Spring 学习笔记《注解方式配置事务》
Spring 事务传播行为 Transaction Propagation
Spring官网 - 定义切点的例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值