简单了解spring中@Transactional注解支持的七种事务的传播行为以及三种常见的事务的场景

简单了解spring中@Transactional注解支持的七种事务的传播行为

简单说一下@Transactional注解的作用吧,看下面的代码

public void deletaAndAddUser() {

	// 根据id删除用户
	deleteUserById(15);

	// 这里会出现算数异常
	int i = 9 / 0;
	
	// 添加用户
	UserInfo user = new UserInfo();
	user.setUserName("派大星");
	addUser(user);
}

如果没有添加@Transactional注解,在这个方法执行到int i = 9 / 0;语句时,就会出现异常。导致 UserInfo user = new UserInfo(); user.setUserName("派大星"); addUser(user); 语句不会被执行,但是deleteUserById(15);却被正常执行了。可是我们的方法是要删除的同时,还要去新增一个用户,这就出现了问题。

在方法上添加@Transactional注解就可以让两个数据库操作方法在一个事务中,也就是删除和新增必须一起执行,如果出现了异常,会回滚事务,也就是不会进行删除和新增(但是如果新增操作执行后回滚事务,MySQL数据库中表中是会自增ID的,假如表中有两条数据,它们的id分别为1 ,2。但是你下一次新增成功的数据,它的自增ID就不是3了,而是4)。

@Transactional
public void deletaAndAddUser() {

	// 根据id删除用户
	deleteUserById(15);

	// 这里会出现算数异常
	int i = 9 / 0;
	
	// 添加用户
	UserInfo user = new UserInfo();
	user.setUserName("派大星");
	addUser(user);
}

@Transactional注解也是可以加在类上的,代表这个类中所有的方法都要应用事务管理的规则。

好的,在简单了解了@Transactional注解的作用后,我们再看一下事务的七种传播行为,也就是@Transactional(propagation =Propagation.REQUIRED ) 后面跟着的(propagation =Propagation.REQUIRED )这个小玩意

  • 事务的七种传播行为
    • REQUIRED(默认):业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务中,否则为自己创建一个新的事务。
    • SUPPORTS:如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
    • NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会给它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。
    • MANDATORY:指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器会抛出异常。
    • REQUIRES_NEW:表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。
    • NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有事务,则表现和REQUIRED。使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效
    • NEVER:业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出异常,只有在业务方法没有关联到任何事务,才能正常执行。

顺便提一嘴,事务失效的场景吧,只提几个比较常见的场景

  • 事务失效的几种常见的场景
    • 异常捕获处理:也就是在@Transactional注解下的方法,使用了try catch 捕获了异常。事务通知只有拿到抛出的异常,才能进行后续的回滚处理。如果自己try catch 捕获了异常,事务无法正常回滚。
    • 非public方法导致的事务失效:Spring中的事务代理,要求方法一定是public的
    • 方法自身使用this调用另一个方法:this会导致引用逃逸,spring的事务代理是基于动态代理的
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@Transactional注解Spring框架常用的事务管理注解,它可以被应用到类或方法上。当它被应用到类上时,它表示所有的方法都将被事务管理;当它被应用到方法上时,它表示该方法将被事务管理。 @Transactional注解可以接受一些参数,包括: 1. propagation:事务传播行为,默认是Propagation.REQUIRED。 2. isolation:事务隔离级别,默认是Isolation.DEFAULT。 3. timeout:事务超时时间,默认是-1,表示使用数据库默认超时时间。 4. readOnly:是否为只读事务,默认是false。 5. rollbackFor:指定哪些异常需要回滚事务。 6. noRollbackFor:指定哪些异常不需要回滚事务。 下面是一些常见事务传播行为: 1. REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务,加入到这个事务。 2. REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。 3. SUPPORTS:支持当前事务,如果当前存在事务,就加入到这个事务,如果当前不存在事务,就以非事务状态执行。 4. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 5. MANDATORY:支持当前事务,如果当前不存在事务,就抛出异常。 6. NEVER:以非事务方式执行操作,如果当前存在事务,就抛出异常。 7. NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则新建一个事务。嵌套事务是独立于父事务的,它有自己的提交和回滚。如果嵌套事务内发生异常,只会回滚当前事务的操作,而不会回滚父事务的操作。 总的来说,@Transactional注解可以让我们更方便地管理事务,避免手动处理事务的繁琐过程。但是,我们需要谨慎使用它,特别是在复杂的应用场景,需要仔细考虑事务传播行为和隔离级别等参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值