Spring中大事务拆分方案
模块设计的时序图
启动流程
激活事件
完成事件
长事务造成的影响
- 由于现在事件的完成及后续激活都在一个事务中,比如完成融资申请事件之后会去激活批次启动签约,前置协议,资质认证等事件,这些操作都在同一个事务中,当某一个激活操作异常时,会导致整个事务回滚,发起融资失败。
- 长事务导致问题定位困难,事件的完成和激活类似于一个长链条,当用户完成一个操作时,在同一个事务中完成其它操作失败,会导致用户操作失败,而报错的内容和用户当前的业务操作没有任务业务关系,对定位问题有很大的影响,也影响用户体验。比如当用户完成零售资产审核时回去激活协议生成,当协议生成失败时会导致用户零售资产审核操作失败。
- 长事务导致数据库锁持有时间长,导致在并发场景下获取连接超时,并发死锁等问题。
- 长事务导致业务重复处理,一个事件完成时,相关的业务操作已完成,当后续激活报错时导致事件完成回滚,但业务操作调用外部接口无法回滚,导致事件再次完成时会重复调用外部接口。
长事务拆分解决方案
通过编程式事务将事件完成方法和激活方法拆分为单独的事务,每个事件只关注当前事件的操作,后续操作异常时由定时任务进行补偿。
长事务拆分需要注意的问题
- 拆分后事务需要提交后才能开启后续事务
- 操作需要串行,会存在多个事务修改同一资产的多个状态
- 事务拆分后需要有事件完成和激活的异常补偿机制