幂等设计
Halo框架为所有在Spring容器中托管声明周期的Bean实例提供了幂等性支持。幂等性是基于消息和事件驱动的流程串联的基础。也是在分布式系统下,基于CAP理论保证原子交易数据一致性的必要条件。 有关服务幂等性概念,可参考如下资料:
http://blog.csdn.net/fbysss/article/details/8024748
http://coolshell.cn/articles/4787.html
幂等方法的声明
在已经注册为SpringBean的服务方法声明开头,添加@Idempotent注解。
如样例代码所示,@Idempotent注解包含以下属性:
expression:采用spEL表达式语法,基于方法参数列表描述该方法执行的幂等要素构成。
关于spEL表达式,请参阅资料:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html
withTranCode:声明该方法执行的幂等性,是否加入线程级的交易码作为幂等要素的一部分。一旦加入则对于不同线程的相同参数列表的请求,会被认为是不同幂等要素的方法调用。该属性默认为false。
expire:幂等要素持久化的过期时限。默认为-1,不过期。由于幂等要素的持久化支持数据库和缓存。对于缓存的持久化,可以通过指定过期时间来提高幂等容器的利用率。
faildInSilence:当幂等校验失败时,是否以静默方式跳过方法的执行。默认值:false(抛出{@link com.halo.core.exception.IdempotentException}异常)。如果为true,则只会在后台打印一条日志通知。同样不会执行方法。
effectOnException:当方法主体抛出异常时,是否将本次作为有效调用,持久化幂等要素信息。默认值:true(无论方法主体是否报错,都作为有效调用)。
幂等方法的校验
已经声明幂等性的服务方法,在被执行时会先经过一个SpringAOP的切面,在切面中,系统会根据已经配置的幂等信息,参数列表和执行记录,判断是否允许再次执行方法。如果校验失败,会根据@Idempotent注解上声明的配置抛出异常或静默跳过:throw new IdempotentException
("识别到重复调用,未通过幂等性校验!");
对于非静默的模式下,服务方法调用的父级建议捕获该异常信息,并做响应处理。
幂等要素的记录存储
为了实现方法的幂等校验,必然涉及到对方法执行的幂等要素记录。框架可以采用数据库或缓存来存储这些幂等要素记录。 对于数据库存储,该表的表结构PDM放在supports-parent/idemp-support/docs文件夹下。如果要使用该组件和特性,需要将PDM中的表结构导入至oracle中。 对于缓存的存储,不需要额外的配置。
幂等性与数据库事务
服务方法的幂等性与数据库事务的融合是一个较为复杂的议题。为了在前期更为清晰的分割两者对于开发者的边界,目前框架将两者的使用强制割裂开。对于幂等要素的数据库存储上会单独启动事务来处理。
Last updated