![04794c53d2e78153e6f3af8c92dc8fdd.png](https://i-blog.csdnimg.cn/blog_migrate/b87fe759a6c7fa235793f0a619e49b13.jpeg)
今天写电商项目的时候遇到一个小问题,就是在订单系统ego-order-web项目中,完成用户下订单的操作的时候,忘记给订单明细表中的字段order_id赋值,这时候,完成这个操作的时候,就出现问题了,因为操作的是3张表:
![95fb656d2b10ae5aa58ee2ba298e7424.png](https://i-blog.csdnimg.cn/blog_migrate/c231706c986c4d8637cc7c9ffadbca3a.jpeg)
订单表:tb_order
![ccefbae237aaebd2dc97136027303287.png](https://i-blog.csdnimg.cn/blog_migrate/3a4a4de79b10ece547ecefb22f3dc48a.jpeg)
订单明细表:tb_order_item
![c65785b3d7d861a6e4cb03026b565df4.png](https://i-blog.csdnimg.cn/blog_migrate/e2d143db45a4ddf9f04eb661388d77d4.jpeg)
订单配送表:tb_order_shipping
![2b6dedf411a72982339889c88c111718.png](https://i-blog.csdnimg.cn/blog_migrate/5564a79f68217e261e0ca7186c5eea95.jpeg)
出错问题:
![97da366eefeabc98a208f9603f8b5fe6.png](https://i-blog.csdnimg.cn/blog_migrate/ce3bb0f6edbdaa944d8e88658700e3e9.jpeg)
远程的rpc服务那边:
![eb951f21aa8b9e3e705f08e38c2c5594.png](https://i-blog.csdnimg.cn/blog_migrate/17520c8a4ba2f7d1212304e2d7742f4c.jpeg)
这里使用了一个try—catch,会对我们发生异常时进行捕获处理,这样一来,当我们在远程调用服务的时候,肯定是不会发生异常的,因为我们已经捕获处理了,并没有往上抛。
这里有一个地方需要理解一下:
![b52f0c3bb56cdb2a1eba399738a97261.png](https://i-blog.csdnimg.cn/blog_migrate/77a060102f2e4b939c6371ba983caf33.jpeg)
Spring的声明式事务是这样配置的,就是rpc服务的实现类的所有方法都用声明式事务进行管理,我们不能这样理解为这里有异常就回滚了,而应该理解为谁调用它,发生异常才会回滚,也就是说,当我们在远程调用服务的时候,发生了异常才会混滚,所以,我们就得把异常往上抛,不然远程调用服务的时候,是无法得到异常的,这样三个表有一个操作失败的时候,是不会进行混滚的,所以我们需要把异常往上抛一下:
![81b80aa4ef04dc268a3daa9db7b4b3aa.png](https://i-blog.csdnimg.cn/blog_migrate/c19cf7ef51b706de9633187fecfeb150.jpeg)
网上查阅了一下资料,发现大佬们都是这样解决的,而且还有其他方法:
默认spring事务只在发生未被捕获的RuntimeException时才回滚。
解决方式:
1:通过throw new RuntimeException();抛出运行时异常,就是我上面说的这种
2.手动回滚
![878b650d06e04010c5e335f481279778.png](https://i-blog.csdnimg.cn/blog_migrate/41c2873bd20928df3d6bc8f68160d85b.jpeg)
3.使用@Transactional注解