@Transactional事务注解,以及在try-catch代码块中的回滚使用

1.使用的范围:

        1.用在类上,那么对该类下所有public方法都有效

        2.也可写在某个方法上(只能是public方法)

2.回滚方式:

        自动回滚:动回滚只需要在对应的方法下添加@Transactional注解,不需要对方法内容进行try-catch

        手动回滚:如果在方法中有使用try-catch,那就需要在捕获异常的地方使用:

        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();如果@Transactional跟手动回滚一起使用的话,那就需要在补获异常的地方手动抛异常,然后使用全局处理注解(需要加@responsebody注解,否则会造被视图解析器解析)来处理

注意:

  • Spring 中 @Transactional ,默认只对抛出的 RuntimeException 的出常,事务才会回滚。

  • 如果希望无论抛出是 RuntimeException ,还是 Exception,事务都要回滚,请使用如下配置。
@Transactional(rollbackFor={RuntimeException.class, Exception.class})

3.使用 Spring中 @Transactional 注解的注意事项

  • @Transactional 的事务是通过基于接口的,或者是基于类的代理才能被创建。在同一个类中一个方法调用另一个有事务注解的方法,事务是不会起作用的。
@Serive
public class XxxService{	
	
	public void aa(){
		//业务...
		bb()
		//业务...
	}
	
	@Transactional
	public void bb(){
		//业务...
	}
}

@Controller
public class XxxController(){
	
	@Autowired
	XxxService xxxService;
	
	@RquestMapping("/hello")
	public void hello(){
		xxxService.aa();
	}
}

XxxController.hello() 调用 XxxService 时,没有开启事务,在 aa()、 bb()发生的RuntimerException 不会事务回滚。

分析说明:
(1)因为 aa() 没有 @Transactional 注解,因此 XxxController 调用 XxxService 时 ,没有开启事务;
(2)aa()中调有 bb() 只是方法的调用(代码片段的调用)。类似于Thread中,开启线程是通过start()方法,而不是直接调用run()方法。

同一个类中,一个没有事务的方法A,去调用另一个有事务的方法B时,因为是直接调用,而不是调用的代理类,所以事务不起用的。

猜你喜欢

转载自blog.csdn.net/qq_26112725/article/details/131064645