springboot事务

1.查看当前事务管理器

	@Resource
	private PlatformTransactionManager platformTransactionManager;

logger.debug("platformTransactionManager:{}", platformTransactionManager);

        springboot默认事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager@1fec5522

2.查看当前方法的事务名称和隔离级别

		logger.debug("currentTransactionName:{},level:{}", TransactionSynchronizationManager.getCurrentTransactionName(),
				TransactionSynchronizationManager.getCurrentTransactionIsolationLevel());

        currentTransactionName:com.ybjdw.order.spotorder.SV.impl.SpotOrderSVImpl.autoReceipt,level:null;事务名称默认是方法的完全限定名称,隔离级别为null,表示使用数据库的隔离级别,注意mysql只有InnoDB引擎才支持事务

3.方法上的事务注解优先于类上的事务注解。

4.spring一个类中,不同方法使用事务注解(不同传播方式和隔离级别),一个方法调用另一个方法,后面的方法事务使用的是前一个方法事务。

        例子:autoReceipt方法调用confirmReceipt方法。

	@Override
	@Transactional
	@Async
	public void autoReceipt() throws Exception
	{
        confirmReceipt("123456");
    }

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
	public String confirmReceipt(String orderId) throws Exception
	{

    }

        查看方法中的事务信息,发现两个方法使用的事务都是com.ybjdw.order.spotorder.SV.impl.SpotOrderSVImpl.autoReceipt,这是因为spring采用动态代理机制来实现事务控制,事务方法内调用另一个方法,使用的是代理类到数据库的同一个连接。

        使用不同事务的解决方法:在调用第二个方法时,通过ApplicationContext获取代理类,再次开启代理类到数据库的连接。

	@Autowired
	private ApplicationContext applicationContext;

ISpotOrderSV spotOrderSV = applicationContext.getBean(ISpotOrderSV.class);
spotOrderSV.confirmReceipt(spotOrder.getOrderId());

        这时查看两个方法的事务信息,会发现两个方法的事务名称不一样了,分别为com.ybjdw.order.spotorder.SV.impl.SpotOrderSVImpl.autoReceipt和com.ybjdw.order.spotorder.SV.impl.SpotOrderSVImpl.confirmReceipt。

5.手动设置提交事务

	@Resource
	private DataSourceTransactionManager dataSourceTransactionManager;
	
	
    DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
		defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); // 设置传播行为
		defaultTransactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); // 设置隔离级别
		TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
		SpotOrder tmpOrder = new SpotOrder();
		tmpOrder.setOrderId("01075604656");
		tmpOrder.setOrderState(1);
		mapper.updateByPrimaryKeySelective(tmpOrder);
		int num = 1/0;
		dataSourceTransactionManager.commit(transactionStatus); // 事务提交

6.事务不生效情况

6.1.方法内捕获了异常,未再抛出异常;

        在下面方法中catch后未再抛出异常;

    @Transactional
    @Override
    public int reduceStock(String invId, int stockNum) {
        int ret=0;
        try{
            ret = unusualMapper.updateInventoryAmount(invId, stockNum);
            return ret;
        }catch (Exception e){
            logger.error("扣减库存异常!", e);
        }
        return ret;
    }
6.2.事务方法捕获异常后,再次抛出的异常与默认回滚异常不一致
    @Transactional
    @Override
    public int reduceStock(String invId, int stockNum) throws Exception{
        int ret=0;
        try{
            ret = unusualMapper.updateInventoryAmount(invId, stockNum);
            return ret;
        }catch (Exception e){
            logger.error("扣减库存异常!", e);
            throw new Exception("扣减库存异常", e);
        }
    }

         spring事务回滚默认只会发生在RuntimeException和Error,不会发生在检查异常(即Exception);解决方法为调整rollbackFor参数,如下即可。

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int reduceStock(String invId, int stockNum) throws Exception{
        int ret=0;
        try{
            ret = unusualMapper.updateInventoryAmount(invId, stockNum);
            return ret;
        }catch (Exception e){
            logger.error("扣减库存异常!", e);
            throw new Exception("扣减库存异常", e);
        }
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
SpringBoot事务是通过使用@EnableTransactionManagement注解在配置类上来开启声明式事务的支持。当使用了@EnableTransactionManagement后,Spring容器会自动扫描注解@Transactional的方法和类。在需要事务的类或方法上使用@Transactional注解即可,当注解在类上时,表示该类的所有public方法都开启事务。被注解的方法成为一个事务整体,共享一个数据库连接,所有操作同时发生。如果在事务内部发生异常,则事务整体会自动回滚。 SpringBoot中的事务隔离级别可以根据具体需要进行配置。事务隔离级别包括读未提交、读已提交、可重复读和串行化。可以通过在@Transactional注解中使用isolation属性来指定事务隔离级别。例如,@Transactional(isolation = Isolation.READ_COMMITTED)表示使用读已提交的事务隔离级别。 @Transactional事务注解由SpringBoot控制,它会在执行具体逻辑时激活事务控制。事务注解的原理是AOP,通过动态代理和反射动态加上事务控制的手动代码逻辑。具体的实现是在逻辑执行前后进行反射动态增强,以实现事务控制的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SpringBoot(八) SpringBoot中的事务](https://blog.csdn.net/qq_40772692/article/details/121476144)[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* [SpringBoot事务使用及回滚实现代码详解](https://download.csdn.net/download/weixin_38527978/12721854)[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 ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值