事务
事务不生效的原因:
@Transactional
1:数据库引擎是否支持
InnoDB支持事务,MyIsam不支持。查看表是什么引擎
1 show create table pms_product;
2:没有被 Spring 管理
1 // @Service 2 public class OrderServiceImpl implements OrderService { 3 4 @Transactional 5 public void updateOrder(Order order) { 6 // update order 7 } 8 9 }
如果此时把 @Service
注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。
3:方法不是 public 的
4:异常被吃了
1 @Override 2 @Transactional 3 public void testTransaction() { 4 log.info("测试事务。修改id=1的值"); 5 PmsProduct pmsProduct = baseMapper.selectById(1L); 6 pmsProduct.setProCreateTime(LocalDateTime.now()); 7 baseMapper.updateById(pmsProduct); 8 try { 9 int j = 1/0; 10 }catch (Exception e){ 11 e.printStackTrace(); 12 } 13 }
把异常吃掉,又不抛出来。事务无法回滚。
5:自调用失效
注解@transactional的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。
自调用是指一个类的一个方法去调用自身另外一个方法的过程。在自调用的过程中,是类自身的调用,而不是代理对象去调用, 那么就不会产生 AOP,这样 Spring就不能把你的代码织入到约定的流程中。
为了克服这个问题,一方面可以写两个Service,用一个Service去调用另一个Service,这样就是代理对象的调用。Spring才会将你的代码织入事务流程。另一方面,也可以从Spring IoC容器中获取代理对象来启用AOP
6:controller层调用service层的事务时,需要捕获到异常。
@ApiOperation("红包领取接口") @ApiImplicitParams({ @ApiImplicitParam(name = "订单号", value = "mchBillno", dataType = "String", paramType = "query") }) @ResponseBody @ApiResource(name = "红包领取接口", path = "/receiveRedPack", requiredPermission = false, requiredLogin = false) public ResponseData receiveRedPack(@RequestParam("mchBillno") String mchBillno) { try { return sendRedPackService.receiveRedPack(mchBillno); } catch (Exception e) { e.printStackTrace(); return ResponseData.error(ResponseData.DEFAULT_ERROR_MESSAGE); } }
/** * @Description 红包领取接口 * @Exception * @param mchBillNo 订单号 * @author heluwei * @Date 2020/4/29 20:02 */ ResponseData receiveRedPack(String mchBillNo) throws Exception;
要不然,事务不起作用。