spring中事务失效场景简介说明

戚薇 Spring 发布时间:2023-07-06 14:53:32 阅读数:7971 1
下文笔者讲述Spring中事务失效场景说明,如下所示

spring中事务失效场景

	一、权限访问问题
	二、方法用final修饰
	三、无事务嵌套有事务的方法
	四、没有被spring管理
	五、设计的表不支持事务
	六、没有开启事务
	七、错误的事务传播
	八、自己捕获了异常
	九、手动抛出别的异常
	十、自定义回滚异常

spring中事务失效场景

一、权限访问问题

当方法不是public的就事务不生效

二、方法用final修饰

spring事务底层实现使用代理
  aop,使用jdk的动态代理或cglib
       生成代理类
	   在代理类中实现了事务功能
       当方法被final修饰,无法重写该方法,也就无法添加事务的功能

三、无事务嵌套有事务的方法

public void testPrivate() {
	testFinal();
}

@Transactional
public  void testFinal(){
	TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
			.blogUrl("www.java265.com").remark("欢迎访问").build();
	userMapper.insertUser(build);
	int i = 1 / 0;
}

四、没有被spring管理

对象没有被Spring管理
  所以@Transactional注解也没有效果哦

五、设计的表不支持事务

数据库不支持事务
  如:
   MySQL使用MyISAM存储引擎

六、没有开启事务

springboot项目
   有自动装配的类DataSourceTransactionManagerAutoConfiguration
    已经默认开启事务
	配置spring.datasource参数就行
    如果是spring项目
	  需在applicationContext.xml配置
	   不然事务不会生效

七、错误事务传播

使用@Transactional注解时
   可指定propagation参数

spring目前支持7种传播特性

REQUIRED 
  如果当前上下文中存在事务,那么加入该事务
   如果不存在事务,创建一个事务,这是默认的传播属性值
SUPPORTS 
  如果当前上下文存在事务,则支持事务加入事务
  如果不存在事务,则使用非事务的方式执行
MANDATORY 
  如果当前上下文中存在事务,否则抛出异常
REQUIRES_NEW 
  每次都会新建一个事务,并且同时将上下文中的事务挂起
   执行当前新建事务完成以后,上下文事务恢复再执行
NOT_SUPPORTED 
  如果当前上下文中存在事务,则挂起当前事务
    然后新的方法在没有事务的环境中执行
NEVER 
  如果当前上下文中存在事务,则抛出异常
    否则在无事务环境上执行代码
NESTED 
  如果当前上下文中存在事务,则嵌套事务执行
   如果不存在事务,则新建事务
 
@Transactional(propagation = Propagation.NEVER)
public  void testFinal(){
	TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
			.blogUrl("www.java265.com").remark("欢迎访问").build();
	userMapper.insertUser(build);
	int i = 1 / 0;
}
 

八、自己捕获了异常

@Transactional
public  void testFinal(){

	TbUser build = null;
	try {
		build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
				.blogUrl("www.java265.com").remark("欢迎访问").build();
		userMapper.insertUser(build);
		int i = 1 / 0;
	} catch (Exception e) {
		System.out.printf(e.toString());
//            throw new RuntimeException(e);
	}
}
 
 在编写事务时,如果我们使用 try catch 捕获了异常
    同时没有手动抛出 异常,则事务不生效(因为不抛出异常,Spring不会捕捉到)
 

九、手动抛出其他异常

@Transactional
public  void testFinal() throws Exception {

	TbUser build = null;
	try {
		build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
				.blogUrl("www.baidu.com").remark("欢迎访问").build();
		userMapper.insertUser(build);
		int i = 1 / 0;
	} catch (Exception e) {
		throw new Exception(e);
//            throw new RuntimeException(e);
	}
}

//上述手动抛出Exception异常
// Spring事务同样不会回滚
由于spring事务
默认情况下不会回滚Exception(非运行时的异常)
  只会回滚RuntimeException(运行时异常)和Error(错误)
 

十、自定义回滚异常

rollbackFor
 默认是RuntimeException 和 Error 及子类抛出,就会回滚
如果 rollbackFor 指定异常类型
   则只有指定的异常及子类发生才会回滚

@Transactional(rollbackFor = BusinessException.class)
public  void query(Demo demo) throws Exception{
	  save(demo);
} 
BusinessException
  是我们自定义异常
  当这个异常发生的时候才会回滚
 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202307/7014.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者