org.springframework.transaction.annotation.Transactional 简单使用示例

测试项目环境

本项目为springboot项目,ORM框架为mybatis,数据库为MySQL8

数据库

DDL

CREATE TABLE `dept_inf` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(50) NOT NULL,
  `REMARK` varchar(300) DEFAULT NULL,
  `NUM` int(11) DEFAULT '0',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;

dept_inf表中当前数据为
在这里插入图片描述

java源码

controller

package com.xl.test.springbootaop.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xl.test.springbootaop.service.DeptInfoService;

@RestController
@RequestMapping("/transaction")
public class TransactionTestController {
	
	@Autowired
	DeptInfoService deptInfoService;
	
	@RequestMapping("/roll")
	public String transactionTest() {
		try {
			deptInfoService.insertTrans();
		} catch (Exception e) {
			return "抛出了异常:"+e.getMessage();
		}
		return "bbb";
	}
}

Service

package com.xl.test.springbootaop.service;

import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.util.CustomException;

public interface DeptInfoService {
	
	/**
	 *  	插入部门信息
	 * @param deptInfo 待插入的部门信息
	 */
	void insert(DeptInfo deptInfo);

	void insertTrans() throws CustomException;
	
}

ServiceImpl

package com.xl.test.springbootaop.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xl.test.springbootaop.dao.DeptInfoMapper;
import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.service.DeptInfoService;
import com.xl.test.springbootaop.util.CustomException;

@Service
//@Transactional
public class DeptInfoServiceImpl implements DeptInfoService {
	
	@Autowired
	DeptInfoMapper deptInfoMapper;
	
	public void insert(DeptInfo deptInfo) {
		if (deptInfo == null) {
			deptInfo = new DeptInfo();
			deptInfo.setNAME("测试001");
			deptInfo.setREMARK("这是测试001");
		}
		deptInfoMapper.insert(deptInfo);
	}

	public void insertTrans() throws CustomException {
		DeptInfo deptInfo1 = new DeptInfo();
		deptInfo1.setNAME("事务测试");
		deptInfo1.setREMARK("事务测试");
		//正常插入, rollback
		deptInfoMapper.insert(deptInfo1);
		
		DeptInfo deptInfo = new DeptInfo();
		deptInfo.setNAME("as");
		deptInfo.setREMARK("rm");
//		try {
			// throws RunTimeException
//			deptInfoMapper.insertTrans(deptInfo);
//		} catch (Exception e) {
			// do nothing...
//		}
		
		// 抛出自定义异常继承自Exception
	   // throw new CustomException("抛出自定义异常");
		
	}

}

mybatis mapper

package com.xl.test.springbootaop.dao;

import org.apache.ibatis.annotations.Insert;

import com.xl.test.springbootaop.entity.DeptInfo;

public interface DeptInfoMapper {
	
	@Insert("INSERT INTO dept_inf(NAME,REMARK) VALUES(#{NAME},#{REMARK})")
	void insert(DeptInfo deptInfo);
	
	@Insert("INSERT INTO dept_inf(NAME1,REMARK1) VALUES(#{NAME},#{REMARK})")
	void insertTrans(DeptInfo deptInfo);
	
}

说明:因为表dept_inf中没有字段 NAME1, REMARK1,所以,在调用方法void insertTrans(DeptInfo deptInfo)会抛出异常。

测试项目

测试一: 在业务实现层,不加@Transactional

代码

package com.xl.test.springbootaop.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xl.test.springbootaop.dao.DeptInfoMapper;
import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.service.DeptInfoService;
import com.xl.test.springbootaop.util.CustomException;

@Service
//@Transactional
public class DeptInfoServiceImpl implements DeptInfoService {
	
	@Autowired
	DeptInfoMapper deptInfoMapper;
	
	public void insert(DeptInfo deptInfo) {
		if (deptInfo == null) {
			deptInfo = new DeptInfo();
			deptInfo.setNAME("测试001");
			deptInfo.setREMARK("这是测试001");
		}
		deptInfoMapper.insert(deptInfo);
	}

	public void insertTrans() throws CustomException {
		DeptInfo deptInfo1 = new DeptInfo();
		deptInfo1.setNAME("事务测试");
		deptInfo1.setREMARK("事务测试");
		//正常插入, rollback
		deptInfoMapper.insert(deptInfo1);
		
		DeptInfo deptInfo = new DeptInfo();
		deptInfo.setNAME("as");
		deptInfo.setREMARK("rm");
	    deptInfoMapper.insertTrans(deptInfo);

	}

}

预期:
尽管

deptInfoMapper.insertTrans(deptInfo);

该行会抛出异常,但是由于没有加@Transactional,就没有事务控制。

所以,下面这行会正常插入

deptInfoMapper.insert(deptInfo1);

验证
在这里插入图片描述
在这里插入图片描述
抛出了异常就,但是数据库仍然插入了数据。

测试二: 在业务层加上@Transactional

package com.xl.test.springbootaop.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xl.test.springbootaop.dao.DeptInfoMapper;
import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.service.DeptInfoService;
import com.xl.test.springbootaop.util.CustomException;

@Service
@Transactional
public class DeptInfoServiceImpl implements DeptInfoService {
	
	@Autowired
	DeptInfoMapper deptInfoMapper;
	
	public void insert(DeptInfo deptInfo) {
		if (deptInfo == null) {
			deptInfo = new DeptInfo();
			deptInfo.setNAME("测试001");
			deptInfo.setREMARK("这是测试001");
		}
		deptInfoMapper.insert(deptInfo);
	}

	public void insertTrans() throws CustomException {
		DeptInfo deptInfo1 = new DeptInfo();
		deptInfo1.setNAME("事务测试");
		deptInfo1.setREMARK("事务测试");
		//正常插入, rollback
		deptInfoMapper.insert(deptInfo1);
		
		DeptInfo deptInfo = new DeptInfo();
		deptInfo.setNAME("as");
		deptInfo.setREMARK("rm");
	    deptInfoMapper.insertTrans(deptInfo);

	}

}

预期

该行插入数据后,

deptInfoMapper.insert(deptInfo1);

由于

deptInfoMapper.insertTrans(deptInfo);

会抛出异常,加上@Transactional事务控制原因,事务会回滚,数据库最终不会有数据。

验证
在这里插入图片描述
在这里插入图片描述

测试三: 抛出自定义异常

package com.xl.test.springbootaop.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xl.test.springbootaop.dao.DeptInfoMapper;
import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.service.DeptInfoService;
import com.xl.test.springbootaop.util.CustomException;

@Service
@Transactional
public class DeptInfoServiceImpl implements DeptInfoService {
	
	@Autowired
	DeptInfoMapper deptInfoMapper;
	
	public void insert(DeptInfo deptInfo) {
		if (deptInfo == null) {
			deptInfo = new DeptInfo();
			deptInfo.setNAME("测试001");
			deptInfo.setREMARK("这是测试001");
		}
		deptInfoMapper.insert(deptInfo);
	}

	public void insertTrans() throws CustomException {
		DeptInfo deptInfo1 = new DeptInfo();
		deptInfo1.setNAME("事务测试");
		deptInfo1.setREMARK("事务测试");
		//正常插入, rollback
		deptInfoMapper.insert(deptInfo1);
				
		// 抛出自定义异常继承自Exception
	    throw new CustomException("抛出自定义异常");
		
	}

}

注意:自定义异常继承自Exception

预期
未知

验证
在这里插入图片描述
在这里插入图片描述

测试四:仍然抛出自定义异常,但是,@Transactional后面加上(rollbackFor = Exception.class)

package com.xl.test.springbootaop.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xl.test.springbootaop.dao.DeptInfoMapper;
import com.xl.test.springbootaop.entity.DeptInfo;
import com.xl.test.springbootaop.service.DeptInfoService;
import com.xl.test.springbootaop.util.CustomException;

@Service
@Transactional(rollbackFor = Exception.class)
public class DeptInfoServiceImpl implements DeptInfoService {
	
	@Autowired
	DeptInfoMapper deptInfoMapper;
	
	public void insert(DeptInfo deptInfo) {
		if (deptInfo == null) {
			deptInfo = new DeptInfo();
			deptInfo.setNAME("测试001");
			deptInfo.setREMARK("这是测试001");
		}
		deptInfoMapper.insert(deptInfo);
	}

	public void insertTrans() throws CustomException {
		DeptInfo deptInfo1 = new DeptInfo();
		deptInfo1.setNAME("事务测试");
		deptInfo1.setREMARK("事务测试");
		//正常插入, rollback
		deptInfoMapper.insert(deptInfo1);
				
		// 抛出自定义异常继承自Exception
	    throw new CustomException("抛出自定义异常");
		
	}

}

验证
在这里插入图片描述

@Transactional官方解释

在这里插入图片描述

在这里插入图片描述

部分翻译

在这里插入图片描述
在这里插入图片描述

附:java异常分类
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值