@Transactional事务嵌套
时间: 2023-11-09 21:01:37 浏览: 37
在Spring中,@Transactional注解可以用于控制事务的提交和回滚。当一个方法被@Transactional注解修饰时,如果该方法抛出异常,则会回滚该方法所在的事务。但是,如果该方法调用了另一个被@Transactional注解修饰的方法,那么这两个方法就会形成一个事务嵌套的关系。
在事务嵌套的情况下,如果内层方法抛出异常,则只会回滚内层方法所在的事务,而外层方法所在的事务不会回滚。如果外层方法抛出异常,则会回滚整个事务,包括内层方法所在的事务。
需要注意的是,事务嵌套只有在使用基于代理的事务管理时才有效。如果使用基于AspectJ的事务管理,则不支持事务嵌套。
相关问题
@Transactional 嵌套@Transactional
@Transactiona注解是Spring框架中用来实现事务管理的注解之一。它可以应用于方法或类级别,并用于标识希望被事务管理的方法或类。当一个方法被标记为@Transactional时,它将在方法执行期间启用事务机制。
关于嵌套@Transactional,引用提到了对子事务的定义和作用。在没有嵌套事务的情况下,如果一个方法A被标记为@Transactional,而方法A又调用了另一个被标记为@Transactional的方法B,那么方法B将会被包含在方法A的事务中。这种情况下,无法实现方法B独立提交或回滚。因此,如果我们想要实现方法B的独立事务控制,就需要使用嵌套@Transactional。
然而,嵌套事务并不是默认情况下就会生效的。实际上,Spring默认的事务传播行为是PROPAGATION_REQUIRED,它会将嵌套事务合并到外层事务中。这意味着,如果嵌套事务失败,整个事务将会回滚。
要使嵌套事务生效,可以通过修改事务传播行为来实现。例如,将内层方法的@Transactional注解的传播行为设置为PROPAGATION_REQUIRES_NEW,即使用@Transactional(propagation = Propagation.REQUIRES_NEW)。这样做的效果是,内层方法将会独立创建一个新的事务,并不会受到外层事务的影响。这样,即使内层事务失败,外层事务也会继续提交。
总结起来,@Transactional注解可以用于实现事务管理,而嵌套@Transactional可以用于实现方法的独立事务控制。通过修改事务传播行为,我们可以实现嵌套事务的独立提交和回滚。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* [Spring的@Transactional 嵌套研究](https://blog.csdn.net/wang_lianjie/article/details/103574836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
- *2* *3* [@Transactional嵌套事务失效异常Transaction rolled back because it has been marked as rollback-only](https://blog.csdn.net/xiyang_1990/article/details/125870203)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"]
[ .reference_list ]
@Transactional 的事务
@Transactional是Spring框架中用于管理事务的注解。在Spring中,我们可以使用@Transactional注解来标记一个方法需要被事务管理器管理。当一个被@Transactional注解标记的方法被调用时,Spring会自动开启一个事务,然后在方法执行完毕后根据方法执行情况决定是提交事务还是回滚事务。
@Transactional注解有多个属性,其中propagation是其中一个重要的属性。propagation用于指定事务的传播行为,即在一个方法调用其他方法时,事务应该如何传播。常用的propagation属性值包括:
- REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入这个事务。- REQUIRES_NEW:不管当前是否存在事务,都会新建一个事务,并在该方法执行完毕后提交该事务。
- SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式执行。
- MANDATORY:必须在一个已有的事务中执行,否则抛出异常。
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则新建一个事务。
下面是一个使用@Transactional注解的例子:
```java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional(propagation = Propagation.REQUIRED)
public void addUser(User user) {
userDao.addUser(user);
}
@Transactional(propagation = Propagation.REQUIRED)
public void updateUser(User user) {
userDao.updateUser(user);
}
@Transactional(propagation = Propagation.REQUIRED)
public void deleteUser(int userId) {
userDao.deleteUser(userId);
}
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public User getUserById(int userId) {
return userDao.getUserById(userId);
}
}
```