Spring对事物的实现

Spring对待事物的实现有一个标签可以使用@Transactional标签来实现事务的管理,但是在使用的时候很多人不清楚实现的原理而使用了错误的使用方式,导致日志里的确是打印了,但是方法的确没有回滚。

我在遇到问题的时候发生了这样的问题,就先去了解下Java中导致程序出现的情况都有哪些

首先Java中的将会导致程序出错的各种情况统称为Throwable,它有两个重要的子类:Exception和Error,二者都是Java异常处理的重要类。

Error是程序已无法处理的异常,与程序员编码无关,是JDK内部出现的问题,一般都是很严重的错误。

Exception是程序自身能处理的异常。

这些异常基本都是可以在编译器发现的,但是除了Exception的一个子类叫做RunTimeException,这个异常只有在运行的过程中才会出现,我们的Try/catch语句,就是为了捕获这种RunimeException,并且处理它,然而我们应该已经被处理的异常是不会再向上抛出的,因为我们已经在这层解决好了,所以一般我们会继承Exception类,把遇到的异常抛出,从而使得Spring的事务管理机制可以捕获到异常,然后回滚。

所以说我们在使用@Transactional进行实现事务的时候,尽量不用Try/catch语句,把异常向上抛出即可。

在别人的博客上我看到了一段代码可以让我很好的理解 :

这段代码,因为已经处理了异常,所以Spring的事务就捕获不到异常信息,导致事务回滚失败

  1. if(userSave){          
  2.     try {         
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);         
  5.      } catch (Exception e) {          
  6.         logger.info("能力开通接口,开户异常,异常信息:"+e);         
  7.      }         
  8.  }  

下面的这种情况,当一个方法出错,抛出一个异常,另一个方法就会回滚:

使用throws关键字把try/catch捕获的异常再一次抛出去

  1. if(userSave){         
  2.      try {          
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);         
  5.        } catch (Exception e) {         
  6.         logger.info("能力开通接口,开户异常,异常信息:"+e);          
  7.         throw new RuntimeException();         
  8.      }          
  9. }  
使用它同样可以达到相同的效果
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 语句,
手动回滚,这样上层就无需去处理异常(现在项目的做法) 

  1. if(userSave){          
  2.     try {          
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);          
  5.     } catch (Exception e) {          
  6.         logger.info("能力开通接口,开户异常,异常信息:"+e);          
  7.         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();         
  8.     }         
  9.  }  













<think>嗯,用户想了解Spring框架中事务管理的实现机制和示例。首先,我需要回忆一下Spring事务管理的基本知识。记得Spring提供了两种事务管理方式:编程式事务和声明式事务。编程式事务需要手动编写代码管理事务的提交和回滚,而声明式事务通过注解或XML配置来管理,更常用。 用户提到的引用内容里,声明式事务使用@Transactional注解,这个注解可以控制传播行为、隔离级别等属性。比如,Propagation.NESTED用于嵌套事务,这可能在处理复杂业务逻辑时有用。另外,还有TransactionTemplate用于编程式事务管理,用户可以通过XML配置或者Bean注入来使用它。 接下来,用户可能需要具体的示例来说明这两种方式如何实现。比如,声明式事务的例子可以用一个服务类的方法加上@Transactional注解,而编程式事务则需要使用TransactionTemplate的execute方法。需要确保示例代码正确,符合Spring的配置方式,比如需要配置事务管理器PlatformTransactionManager,并在XML中启用注解驱动的事务管理。 另外,用户的问题可能涉及事务的传播行为和隔离级别,比如REQUIRED和READ_COMMITTED,这些属性在@Transactional中设置。引用中提到的嵌套事务Propagation.NESTED也是一个需要注意的点,需要解释清楚它的应用场景。 可能还需要区分编程式和声明式事务的适用场景。编程式事务更灵活,适合需要细粒度控制的场景,而声明式事务简化了代码,适合大多数常见情况。同时,要提到事务管理器的作用,比如DataSourceTransactionManager用于JDBC事务,而HibernateTransactionManager用于Hibernate。 用户可能会对事务实现机制有疑问,比如AOP在声明式事务中的应用。Spring通过AOP代理来拦截带有@Transactional的方法,在方法执行前后管理事务的开始、提交或回滚。这一点需要解释清楚,但引用中没有直接提到,可能需要结合已有的知识补充。 还需要注意示例的正确性,比如在编程式事务中,TransactionTemplate需要注入事务管理器,而声明式事务需要在配置类上添加@EnableTransactionManagement或在XML中配置<tx:annotation-driven/>。 最后,用户可能需要了解事务回滚的规则,比如默认情况下遇到运行时异常回滚,检查型异常不回滚,但可以通过@Transactional的rollbackFor属性进行配置。引用中的例子提到了嵌套事务的回滚处理,需要说明父事务和子事务之间的关系。 总结下来,回答需要涵盖两种事务管理方式,各自的实现方法,示例代码,配置方式,以及相关属性的解释。同时结合用户提供的引用内容,确保引用标识正确添加,比如使用声明式事务的部分引用[^1],嵌套事务引用[^2],配置示例引用[^4]等。</think>### Spring框架事务管理实现机制分步说明 #### 一、事务管理核心组件 Spring事务管理基于`PlatformTransactionManager`接口实现,主要实现类包括: - `DataSourceTransactionManager`(JDBC事务) - `HibernateTransactionManager`(Hibernate事务) - `JpaTransactionManager`(JPA事务) 配置示例(XML方式): ```xml <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> [^4] ``` #### 二、声明式事务实现(主流方式) 1. **注解驱动配置** ```java @Configuration @EnableTransactionManagement // 开启事务注解支持 public class AppConfig { @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } } ``` 2. **事务方法示例** ```java @Service public class OrderService { @Transactional( propagation = Propagation.REQUIRED, // 默认传播行为[^1] isolation = Isolation.READ_COMMITTED, timeout = 30, rollbackFor = {SQLException.class} ) public void createOrder(Order order) { // 数据库操作1 inventoryService.deductStock(); // 嵌套事务调用 // 数据库操作2 } } ``` #### 三、编程式事务实现 通过`TransactionTemplate`控制事务边界: ```java public class PaymentService { private final TransactionTemplate transactionTemplate; public PaymentService(PlatformTransactionManager txManager) { this.transactionTemplate = new TransactionTemplate(txManager); } public void processPayment() { transactionTemplate.execute(status -> { try { // 事务操作1 // 事务操作2 return true; } catch (Exception ex) { status.setRollbackOnly(); // 手动回滚[^3] return false; } }); } } ``` #### 四、事务传播行为对照表 | 传播类型 | 说明 | |-------------------|----------------------------------------------------------------------| | REQUIRED(默认) | 当前有事务则加入,没有则新建 | | NESTED | 在现有事务中嵌套子事务,可部分回滚[^2] | | REQUIRES_NEW | 始终新建独立事务 | #### 五、事务监控配置建议 ```properties # 开启事务调试日志 logging.level.org.springframework.transaction.interceptor=TRACE logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值