补偿方案

为什么需要补偿方案呢?

有时候可能因为时间差,或者是无法实时获取正确的结果,就需要一套补偿方案。

补偿方案可以设计的很复杂,比如基于数据库+mq,也可以设计的很简单,比如基于内存+定时任务。

我们今天主要讲解一个比较简单的设计方案: 内存 + 定时任务。

整体预期

可以指定补偿次数

可以指定补偿的时间间隔?

可以查询当前补偿的状态 + 对补偿的数据进行 CRUD 管理。(前期可以不需要页面)

不同的实现策略

基于内存的

基于数据库的(允许自定义)

什么时候需要补偿

补偿应该是一个偶发性的动作,如果非常常见,首先应该考虑是不是功能设计有问题,或者程序存在 BUG。

一般都是存在异常的时候。

所以我们可以定义一个异常,或者当特定的情况下抛出这个异常。

ps: 这个设计理念类似于 spring 的事务管理。

异常的定义

我们专门定义一个异常,用于区分其他的各种异常。

只有当抛出的是这个异常的时候,才进行处理。

package com.github.houbb.compensate.api.exception;

/**
 * 当需要补偿的时候,需要抛出这个异常。
 * 
 * @author binbin.hou
 * @since 1.0.0
 */
public class RequireCompensateException extends CompensateException {

    public RequireCompensateException() {
    }

    public RequireCompensateException(String message) {
        super(message);
    }

    public RequireCompensateException(String message, Throwable cause) {
        super(message, cause);
    }

    public RequireCompensateException(Throwable cause) {
        super(cause);
    }

    public RequireCompensateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

存储的设计

当抛出异常的时候,这个时候上下文信息应该放在那里呢?

和重试的差异性要如何体现呢?

这里为了充分的将二者区分开,或者说将二者融合也是一个不错的方案?

为了简单和后续的自由发展,我们暂时将二者区分开。

我们认为,补偿甚至是有些类似于 spring 中的熔断等等方法。

注解定义

基本属性

当前补偿次数

历史

时间

入参

结果