举例说明如果在同一个类中调用被 @Transactional 注解修饰的方法,事务将不会生效。
时间: 2023-10-19 08:12:11 浏览: 94
Java注解@Transactional事务类内调用不生效问题及解决办法
假设我们有一个 UserService 类,其中有两个方法 addUser 和 deleteUser,它们都被 @Transactional 注解修饰:
```
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void addUser(User user) {
userRepository.save(user);
}
@Transactional
public void deleteUser(Long userId) {
userRepository.deleteById(userId);
// 抛出异常来模拟事务回滚
throw new RuntimeException("deleteUser failed");
}
}
```
现在我们在 addUser 方法中调用 deleteUser 方法:
```
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void addUser(User user) {
userRepository.save(user);
deleteUser(user.getId());
}
@Transactional
public void deleteUser(Long userId) {
userRepository.deleteById(userId);
// 抛出异常来模拟事务回滚
throw new RuntimeException("deleteUser failed");
}
}
```
然后我们在业务逻辑中调用 addUser 方法:
```
@Service
public class BusinessService {
@Autowired
private UserService userService;
@Transactional
public void addUser(User user) {
userService.addUser(user);
}
}
```
我们期望的是,当 addUser 方法执行失败时,整个事务能够回滚。但是实际上,当 addUser 方法调用 deleteUser 方法时,deleteUser 方法的事务不会生效,因为它们都在同一个类中。这意味着,当 deleteUser 方法抛出异常时,addUser 方法中保存的 user 记录不会被回滚,而 deleteUser 方法中删除的 userId 记录也不会被回滚,导致数据不一致。
因此,如果在同一个类中调用被 @Transactional 注解修饰的方法,事务将不会生效。为了避免这种情况,我们应该将这些方法放在不同的类中,或者在同一个类中使用 AOP 来确保事务生效。
阅读全文