@Transactional—事务注解实现锁

事务注解@Transactional

概述

声明式事务管理建立在AOP之上。 其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

使用

1、在Service上添加@Transactional,可以将整个类纳入spring事务管理,在每个业务方法执行时都会开启一个事务,不过这些事务采用相同的管理方式。 2、@Transactional 注解只能应用到 public 可见度的方法上。 如果应用在protected、private或者 package可见度的方法上,也不会报错,不过事务设置不会起作用。 3、默认情况下,Spring会对unchecked异常进行事务回滚;如果是checked异常则不回滚。 (java里面将派生于Error或者RuntimeException(比如空指针,1/0)的异常称为unchecked异常,其他继承自java.lang.Exception得异常统称为Checked Exception,如IOException、TimeoutException等) 加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚。

事务的传播模式

Propagation枚举了多种事务传播模式,部分列举如下:

1、REQUIRED(默认模式):业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。 2、NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。 3、REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。 4、 MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。 5、SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。 6、NEVER:该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。 7、NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

Transactional注解失效原因

1、@Transactional 应用在非 public 修饰的方法上。 2、@Transactional 注解属性 rollbackFor 设置错误: rollbackFor 可以指定能够触发事务回滚的异常类型。 如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定rollbackFor属性。 3、同一个类中方法调用,导致@Transactional失效。

@Service
public class UserService {
@Autowired
private UserMapper userMapper;

//如果先调用deleteUser(),那么deleteUserA()是不会回滚的
//public void deleteUser() throws MyException{ deleteUser2(); }

//需要自己注入自己,再调用deleteUser(),那么deleteUserA()会回滚
@Autowired
UserService userService;

public void deleteUser() throws MyException{ userService.deleteUser2(); }

@Transactional
public void deleteUser2() throws MyException{
userMapper.deleteUserA();
int i = 1 / 0;
userMapper.deleteUserB();
}
}

4、异常被处理了:只有捕获到异常才会回滚,如果catch 处理了,就捕获不到异常,事务就不会回滚。 5、数据库引擎不支持事务。 6、开启多线程任务时,事务管理会受到影响。

posted @ 2022-06-08 16:57  X_peng  阅读(405)  评论(0编辑  收藏  举报