各大招聘网站,上海网页制作方法,wordpress文章归档插件,网络营销是什么工作职位在日常工作中#xff0c;如果对Spring的事务管理功能使用不当#xff0c;则会造成Spring事务不生效的问题。而针对Spring事务不生效的问题#xff0c;也是在跳槽面试中被问的比较频繁的一个问题。点击上方卡片关注我今天#xff0c;我们就一起梳理下有哪些场景会导致Spring… 在日常工作中如果对Spring的事务管理功能使用不当则会造成Spring事务不生效的问题。而针对Spring事务不生效的问题也是在跳槽面试中被问的比较频繁的一个问题。点击上方卡片关注我今天我们就一起梳理下有哪些场景会导致Spring事务生效。Spring事务不生效总览简单来说Spring事务会在几种特定的场景下失效如下图所示。1.数据库不支持事务Spring事务生效的前提是所连接的数据库要支持事务如果底层的数据库都不支持事务则Spring的事务肯定会失效。例如如果使用的数据库为MySQL并且选用了MyISAM存储引擎则Spring的事务就会失效。2.事务方法未被Spring管理如果事务方法所在的类没有加载到Spring IOC容器中也就是说事务方法所在的类没有被Spring管理则Spring事务会失效示例如下。public class ProductService {Autowiredprivate ProductDao productDao;Transactional(propagation Propagation.REQUIRES_NEW)public void updateProductStockCountById(Integer stockCount, Long id){productDao.updateProductStockCountById(stockCount, id);}
}ProductService类上没有标注Service注解Product的实例没有加载到Spring IOC容器中就会造成updateProductStockCountById()方法的事务在Spring中失效。3.方法没有被public修饰如果事务所在的方法没有被public修饰此时Spring的事务会失效例如如下代码所示。Service
public class ProductService {Autowiredprivate ProductDao productDao;Transactional(propagation Propagation.REQUIRES_NEW)private void updateProductStockCountById(Integer stockCount, Long id){productDao.updateProductStockCountById(stockCount, id);}
}虽然ProductService上标注了Service注解同时updateProductStockCountById()方法上标注了Transactional(propagation Propagation.REQUIRES_NEW)注解。但是由于updateProductStockCountById()方法为内部的私有方法使用private修饰那么此时updateProductStockCountById()方法的事务在Spring中会失效。4.同一类中方法调用如果同一个类中的两个方法分别为A和B方法A上没有添加事务注解方法B上添加了 Transactional事务注解方法A调用方法B则方法B的事务会失效。例如如下代码所示。Service
public class OrderService {Autowiredprivate OrderDao orderDao;Autowiredprivate ProductDao productDao;public void submitOrder(){//生成订单Order order new Order();long number Math.abs(new Random().nextInt(500));order.setId(number);order.setOrderNo(order_ number);orderDao.saveOrder(order);//减库存this.updateProductStockCountById(1, 1L);}Transactional(propagation Propagation.REQUIRES_NEW)public void updateProductStockCountById(Integer stockCount, Long id){productDao.updateProductStockCountById(stockCount, id);}
}submitOrder()方法和updateProductStockCountById()方法都在OrderService类中submitOrder()方法上没有标注事务注解updateProductStockCountById()方法上标注了事务注解submitOrder()方法调用了updateProductStockCountById()方法此时updateProductStockCountById()方法的事务在Spring中会失效。5.未配置事务管理器如果在项目中没有配置Spring的事务管理器即使使用了Spring的事务管理功能Spring的事务也不会生效。例如没有在项目的配置类中配置如下代码。Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
}此时Spring的事务就会失效。6.方法的事务传播类型不支持事务如果内部方法的事务传播类型为不支持事务的传播类型则内部方法的事务在Spring中会失效。例如如下代码所示。Service
public class OrderService {Autowiredprivate OrderDao orderDao;Autowiredprivate ProductDao productDao;Transactional(propagation Propagation.REQUIRED)public void submitOrder(){//生成订单Order order new Order();long number Math.abs(new Random().nextInt(500));order.setId(number);order.setOrderNo(order_ number);orderDao.saveOrder(order);//减库存this.updateProductStockCountById(1, 1L);}Transactional(propagation Propagation.NOT_SUPPORTED)public void updateProductStockCountById(Integer stockCount, Long id){productDao.updateProductStockCountById(stockCount, id);}
}由于updateProductStockCountById()方法的事务传播类型为NOT_SUPPORTED不支持事务则updateProductStockCountById()方法的事务会在Spring中失效。7.不正确的捕获异常不正确的捕获异常也会导致Spring的事务失效示例如下。Service
public class OrderService {Autowiredprivate OrderDao orderDao;Autowiredprivate ProductDao productDao;Transactional(propagation Propagation.REQUIRED)public void submitOrder(){//生成订单Order order new Order();long number Math.abs(new Random().nextInt(500));order.setId(number);order.setOrderNo(order_ number);orderDao.saveOrder(order);//减库存this.updateProductStockCountById(1, 1L);}Transactional(propagation Propagation.REQUIRED)public void updateProductStockCountById(Integer stockCount, Long id){try{productDao.updateProductStockCountById(stockCount, id);int i 1 / 0;}catch(Exception e){logger.error(扣减库存异常:, e.getMesaage());}}
}updateProductStockCountById()方法中使用try-catch代码块捕获了异常即使updateProductStockCountById()方法内部会抛出异常但也会被catch代码块捕获到此时updateProductStockCountById()方法的事务会提交而不会回滚并且submitOrder()方法的事务会提交而不会回滚这就造成了Spring事务的回滚失效问题。8.错误的标注异常类型如果在Transactional注解中标注了错误的异常类型则Spring事务的回滚会失效示例如下。Transactional(propagation Propagation.REQUIRED)
public void updateProductStockCountById(Integer stockCount, Long id){try{productDao.updateProductStockCountById(stockCount, id);}catch(Exception e){logger.error(扣减库存异常:, e.getMesaage());throw new Exception(扣减库存异常);}
}在updateProductStockCountById()方法中捕获了异常并且在异常中抛出了Exception类型的异常此时updateProductStockCountById()方法事务的回滚会失效。为何会失效呢这是因为Spring中对于默认回滚的事务异常类型为RuntimeException上述代码抛出的是Exception异常。默认情况下Spring事务中无法捕获到Exception异常所以此时updateProductStockCountById()方法事务的回滚会失效。此时可以手动指定updateProductStockCountById()方法标注的事务异常类型如下所示。Transactional(propagation Propagation.REQUIRED,rollbackFor Exception.class)这里需要注意的是Spring事务注解Transactional中的rollbackFor属性可以指定 Throwable 异常类及其子类。好了今天就到这儿吧我们下期见~~