分布式事务——hmily主流程源码分析
1. 前提
以上一篇《分布式事务——Dubbo集成hmily使用》
为例,RPC框架为Apache Dubbo
,TCC
分布式事务模式,进行hmily分布式事务主流程源码分析。hmily版本2.2.1
项目maven依赖:
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily-spring-boot-starter-apache-dubbo</artifactId>
</dependency>
2. 主流程图
3. 源码分析
1. 自动化配置
hmily-spring-boot-starter-parent
HmilyAutoConfiguration
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class HmilyAutoConfiguration {
/**
* 分布式事务注解切面逻辑
*/
@Bean
public SpringHmilyTransactionAspect hmilyTransactionAspect() {
return new SpringHmilyTransactionAspect();
}
/**
* 存储Dubbo RPC的字段实例
*/
@Bean
@ConditionalOnProperty(value = "hmily.support.rpc.annotation", havingValue = "true")
public BeanPostProcessor refererAnnotationBeanPostProcessor() {
return new RefererAnnotationBeanPostProcessor();
}
/**
* hmily需要的资源启动类
*/
@Bean
@Qualifier("hmilyTransactionBootstrap")
@Primary
public HmilyApplicationContextAware hmilyTransactionBootstrap() {
return new HmilyApplicationContextAware();
}
}
2. 注解切面逻辑
hmily分布式事务的主体流程主要在SpringHmilyTransactionAspect
中
AbstractHmilyTransactionAspect
@Aspect
public abstract class AbstractHmilyTransactionAspect {
private final HmilyTransactionInterceptor interceptor = new HmilyGlobalInterceptor();
/**
* @HmilyTCC/@HmilyTAC注解生效
*/
@Pointcut("@annotation(org.dromara.hmily.annotation.HmilyTCC) || @annotation(org.dromara.hmily.annotation.HmilyTAC)")
public void hmilyInterceptor() {
}
@Around("hmilyInterceptor()")
public Object interceptTccMethod(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
return interceptor.interceptor(proceedingJoinPoint);
}
}
HmilyTransactionInterceptor
public class HmilyGlobalInterceptor implements HmilyTransactionInterceptor {
/**
* Apache Dubbo实现
* {@link org.dromara.hmily.dubbo.parameter.DubboParameterLoader}
*/
private static RpcParameterLoader parameterLoader;
static {
parameterLoader = Optional.ofNullable(ExtensionLoaderFactory.load(RpcParameterLoader.class)).orElse(new LocalParameterLoader());
}
@Override
public Object interceptor(final ProceedingJoinPoint pjp) throws Throwable {
// 构建HmilyTransactionContext,Apache Dubbo的实现为RpcContext.getContext()::getAttachment获取RPC上下文
HmilyTransactionContext context = parameterLoader.load();
// 返回处理类处理后的结果
return HmilyTransactionAspectInvoker.getInstance().invoke(context, pjp);
}
}
interceptor()
中根据SPI机制获取RpcParameterLoader
实现类,调用实现类中的load()
获取HmilyTransactionContext
,做为参数传入处理类。
RpcParameterLoader
在Apache Dubbo
中的实现类为DubboParameterLoader
,从RPC上下文中获取参数
DubboParameterLoader
@HmilySPI(value = "dubbo")
public class DubboParameterLoader implements RpcParameterLoader {
@Override
public HmilyTransactionContext load() {
return Optional.ofNullable(RpcMediator.getInstance().acquire(RpcContext.getContext()::getAttachment)).orElse(HmilyContextHolder.get());
}
}
RpcMediator.getInstance().acquire()
作用是构建HmilyTransactionContext
public HmilyTransactionContext acquire(final RpcAcquire rpcAcquire) {
HmilyTransactionContext hmilyTransactionContext = null;
// 从Rpc上下文中获取参数_HMILY_TRANSACTION_CONTEXT值
final String context = rpcAcquire.acquire(CommonConstant.HMILY_TRANSACTION_CONTEXT);
if (StringUtils.isNoneBlank(context)) {
// string转为HmilyTransactionContext对象
hmilyTransactionContext = GsonUtils.getInstance().fromJson(context, HmilyTransactionContext.class);
}
return hmilyTransactionContext;
}
HmilyTransactionAspectInvoker.invoke()
:选择TCC
\ TAC
处理类处理
public Object invoke(final HmilyTransactionContext hmilyTransactionContext, final ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
final HmilyTCC hmilyTCC = method.getAnnotation(HmilyTCC.class);
if (null != hmilyTCC) {
// 获取处理类后调用handler方法处理
return FACTORY_MAP.get(TransTypeEnum.TCC).factoryOf(hmilyTransactionContext).handler(point, hmilyTransactionContext);
} else {
return FACTORY_MAP.get(TransTypeEnum.TAC).factoryOf(hmilyTransactionContext).handler(point, hmilyTransactionContext);
}
}
AbstractHmilyTransactionHandlerFactory.factoryOf()
/**
* 根据事务的角色选择处理类
*/
@Override
public HmilyTransactionHandler factoryOf(final HmilyTransactionContext context) {
if (Objects.isNull(context)) {
return getMap().get(HmilyRoleEnum.START);
} else {
// if context not null and role is inline is ParticipantHmilyTransactionHandler.
if (context.getRole() == HmilyRoleEnum.LOCAL.getCode()) {
return getMap().get(HmilyRoleEnum.LOCAL);
} else if (context.getRole() == HmilyRoleEnum.PARTICIPANT.getCode()
|| context.getRole() == HmilyRoleEnum.START.getCode()) {
return getMap().get(HmilyRoleEnum.PARTICIPANT);
}
return getMap().get(HmilyRoleEnum.CONSUMER);
}
}
TCC
模式处理类HmilyTccTransactionHandlerFactory
@HmilySPI("tcc")
public class HmilyTccTransactionHandlerFactory extends AbstractHmilyTransactionHandlerFactory {
private static final Map<HmilyRoleEnum, HmilyTransactionHandler> HANDLER_MAP = new EnumMap<>(HmilyRoleEnum.class);
static {
// 根据事务角色选择逻辑处理类
HANDLER_MAP.put(HmilyRoleEnum.START, new StarterHmilyTccTransactionHandler());
HANDLER_MAP.put(HmilyRoleEnum.PARTICIPANT, new ParticipantHmilyTccTransactionHandler());
HANDLER_MAP.put(HmilyRoleEnum.CONSUMER, new ConsumeHmilyTccTransactionHandler());
HANDLER_MAP.put(HmilyRoleEnum.LOCAL, new LocalHmilyTccTransactionHandler());
}
@Override
protected Map<HmilyRoleEnum, HmilyTransactionHandler> getMap() {
return HANDLER_MAP;
}
}
这里只分析事务发起者处理类StarterHmilyTccTransactionHandler
和事务参与者处理类ParticipantHmilyTccTransactionHandler
3. 事务发起者处理器StarterHmilyTccTransactionHandler
StarterHmilyTccTransactionHandler.handler()
@Override
public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context)
throws Throwable {
Object returnValue;
Supplier<Boolean> histogramSupplier = null;
// 指标数据相关
Optional<MetricsHandlerFacade> handlerFacade = MetricsHandlerFacadeEngine.load();
try {
if (handlerFacade.isPresent()) {
handlerFacade.get().counterIncrement(MetricsLabelEnum.TRANSACTION_TOTAL.getName(), TransTypeEnum.TCC.name());
histogramSupplier = handlerFacade.get().histogramStartTimer(MetricsLabelEnum.TRANSACTION_LATENCY.getName(), TransTypeEnum.TCC.name());
}
// 构建HmilyTransactionContext等
HmilyTransaction hmilyTransaction = executor.preTry(point);
try {
//execute try
// 执行try方法
returnValue = point.proceed();
hmilyTransaction.setStatus(HmilyActionEnum.TRYING.getCode());
// 更新发布者状态,并查询参与者及更新状态
executor.updateStartStatus(hmilyTransaction);
} catch (Throwable throwable) {
//if exception ,execute cancel
final HmilyTransaction currentTransaction = HmilyTransactionHolder.getInstance().getCurrentTransaction();
disruptorProviderManage.getProvider().onData(() -> {
handlerFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(),
TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CANCELING.name()));
// 有异常进行全局回滚
executor.globalCancel(currentTransaction);
});
throw throwable;
}
//execute confirm
final HmilyTransaction currentTransaction = HmilyTransactionHolder.getInstance().getCurrentTransaction();
disruptorProviderManage.getProvider().onData(() -> {
handlerFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(),
TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CONFIRMING.name()));
// 执行全局confirm()
executor.globalConfirm(currentTransaction);
});
} finally {
HmilyContextHolder.remove();
executor.remove();
if (null != histogramSupplier) {
histogramSupplier.get();
}
}
return returnValue;
}
步骤:
executor.preTry()
中构建HmilyTransaction、HmilyTransactionContext等;- 执行发起者的
try()
; try()
执行成功,更新事务状态,异步执行全局confirm()
;try()
执行异常,异步执行全局cancel()
;
HmilyTccTransactionExecutor.preTry()
public HmilyTransaction preTry(final ProceedingJoinPoint point) {
LogUtil.debug(LOGGER, () -> "......hmily tcc transaction starter....");
// 构建HmilyTransaction
HmilyTransaction hmilyTransaction = createHmilyTransaction();
// HmilyRepositoryEventPublisher发布 创建全局事务事件
HmilyRepositoryStorage.createHmilyTransaction(hmilyTransaction);
// 构建事务参与者
HmilyParticipant hmilyParticipant = buildHmilyParticipant(point, null, null, HmilyRoleEnum.START.getCode(), hmilyTransaction.getTransId());
// HmilyRepositoryEventPublisher发布 创建参与者事件
HmilyRepositoryStorage.createHmilyParticipant(hmilyParticipant);
// 参与者加入到全局事务HmilyTransaction中
hmilyTransaction.registerParticipant(hmilyParticipant);
// 保存HmilyTransaction到ThreadLocal中
HmilyTransactionHolder.getInstance().set(hmilyTransaction);
// 构建HmilyTransactionContext
HmilyTransactionContext context = new HmilyTransactionContext();
context.setAction(HmilyActionEnum.TRYING.getCode());
context.setTransId(hmilyTransaction.getTransId());
context.setRole(HmilyRoleEnum.START.getCode());
context.setTransType(TransTypeEnum.TCC.name());
// 保存HmilyTransactionContext到HmilyContextHolder
HmilyContextHolder.set(context);
return hmilyTransaction;
}
HmilyTccTransactionExecutor.updateStartStatus()
:更新事务状态
public void updateStartStatus(final HmilyTransaction hmilyTransaction) {
// HmilyRepositoryEventPublisher更新全局事务状态
HmilyRepositoryStorage.updateHmilyTransactionStatus(hmilyTransaction);
// 筛选出发起者
HmilyParticipant hmilyParticipant = filterStartHmilyParticipant(hmilyTransaction);
if (Objects.nonNull(hmilyParticipant)) {
// 更新发起者状态
hmilyParticipant.setStatus(hmilyTransaction.getStatus());
// HmilyRepositoryEventPublisher更新参与者状态
HmilyRepositoryStorage.updateHmilyParticipantStatus(hmilyParticipant);
}
}
HmilyTccTransactionExecutor.globalConfirm()
:执行全局confirm()
public void globalConfirm(final HmilyTransaction currentTransaction) throws HmilyRuntimeException {
LogUtil.debug(LOGGER, () -> "hmily transaction confirm .......!start");
if (Objects.isNull(currentTransaction) || CollectionUtils.isEmpty(currentTransaction.getHmilyParticipants())) {
return;
}
// 当前事务状态更新为CONFIRMING
currentTransaction.setStatus(HmilyActionEnum.CONFIRMING.getCode());
// 更新全局事务状态
HmilyRepositoryStorage.updateHmilyTransactionStatus(currentTransaction);
final List<HmilyParticipant> hmilyParticipants = currentTransaction.getHmilyParticipants();
List<Boolean> successList = new ArrayList<>();
// 循环参与者,执行confirm()方法
for (HmilyParticipant hmilyParticipant : hmilyParticipants) {
try {
if (hmilyParticipant.getRole() == HmilyRoleEnum.START.getCode()) {
HmilyReflector.executor(HmilyActionEnum.CONFIRMING, ExecutorTypeEnum.LOCAL, hmilyParticipant);
HmilyRepositoryStorage.removeHmilyParticipant(hmilyParticipant);
} else {
HmilyReflector.executor(HmilyActionEnum.CONFIRMING, ExecutorTypeEnum.RPC, hmilyParticipant);
}
successList.add(true);
} catch (Throwable e) {
successList.add(false);
LOGGER.error("HmilyParticipant confirm exception param:{} ", hmilyParticipant.toString(), e);
} finally {
HmilyContextHolder.remove();
}
}
if (successList.stream().allMatch(e -> e)) {
// remove global
// 删除全局日志
HmilyRepositoryStorage.removeHmilyTransaction(currentTransaction);
}
}
这里根据参与者的角色,如果是START(发起者)
,则使用反射调用本地方法;如果是其他角色,则进行RPC远程调用;
HmilyReflector.executor()
public static Object executor(final HmilyActionEnum action, final ExecutorTypeEnum executorType, final HmilyParticipant hmilyParticipant) throws Exception {
if (executorType == ExecutorTypeEnum.RPC && hmilyParticipant.getRole() != HmilyRoleEnum.START.getCode()) {
setContext(action, hmilyParticipant);
// 执行RPC调用的confirm()或cancel()
if (action == HmilyActionEnum.CONFIRMING) {
return executeRpc(hmilyParticipant.getConfirmHmilyInvocation());
} else {
return executeRpc(hmilyParticipant.getCancelHmilyInvocation());
}
} else {
if (action == HmilyActionEnum.CONFIRMING) {
return executeLocal(hmilyParticipant.getConfirmHmilyInvocation(), hmilyParticipant.getTargetClass(), hmilyParticipant.getConfirmMethod());
} else {
return executeLocal(hmilyParticipant.getConfirmHmilyInvocation(), hmilyParticipant.getTargetClass(), hmilyParticipant.getCancelMethod());
}
}
}
HmilyTccTransactionExecutor.globalCancel()
:执行全局cancel()
public void globalCancel(final HmilyTransaction currentTransaction) {
LogUtil.debug(LOGGER, () -> "tcc cancel ...........start!");
if (Objects.isNull(currentTransaction) || CollectionUtils.isEmpty(currentTransaction.getHmilyParticipants())) {
return;
}
// 更新当前事务状态CANCELING
currentTransaction.setStatus(HmilyActionEnum.CANCELING.getCode());
//update cancel
HmilyRepositoryStorage.updateHmilyTransactionStatus(currentTransaction);
final List<HmilyParticipant> hmilyParticipants = currentTransaction.getHmilyParticipants();
// 循环参与者进行回滚
for (HmilyParticipant hmilyParticipant : hmilyParticipants) {
try {
if (hmilyParticipant.getRole() == HmilyRoleEnum.START.getCode()) {
HmilyReflector.executor(HmilyActionEnum.CANCELING, ExecutorTypeEnum.LOCAL, hmilyParticipant);
HmilyRepositoryStorage.removeHmilyParticipant(hmilyParticipant);
} else {
HmilyReflector.executor(HmilyActionEnum.CANCELING, ExecutorTypeEnum.RPC, hmilyParticipant);
}
} catch (Throwable e) {
LOGGER.error("HmilyParticipant cancel exception :{}", hmilyParticipant.toString(), e);
} finally {
HmilyContextHolder.remove();
}
}
}
4. 事务参与者处理器ParticipantHmilyTccTransactionHandler
ParticipantHmilyTccTransactionhandler.handler()
public Object handler(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable {
HmilyParticipant hmilyParticipant = null;
switch (HmilyActionEnum.acquireByCode(context.getAction())) {
case TRYING:
try {
hmilyParticipant = executor.preTryParticipant(context, point);
final Object proceed = point.proceed();
hmilyParticipant.setStatus(HmilyActionEnum.TRYING.getCode());
//update log status to try
HmilyRepositoryStorage.updateHmilyParticipantStatus(hmilyParticipant);
return proceed;
} catch (Throwable throwable) {
//if exception ,delete log.
if (Objects.nonNull(hmilyParticipant)) {
HmilyParticipantCacheManager.getInstance().removeByKey(hmilyParticipant.getParticipantId());
}
HmilyRepositoryStorage.removeHmilyParticipant(hmilyParticipant);
throw throwable;
} finally {
HmilyContextHolder.remove();
}
case CONFIRMING:
MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(),
TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CONFIRMING.name()));
List<HmilyParticipant> confirmList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId());
return executor.participantConfirm(confirmList, context.getParticipantId());
case CANCELING:
MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(),
TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CANCELING.name()));
List<HmilyParticipant> cancelList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId());
return executor.participantCancel(cancelList, context.getParticipantId());
default:
break;
}
Method method = ((MethodSignature) (point.getSignature())).getMethod();
return DefaultValueUtils.getDefaultValue(method.getReturnType());
}
根据上下文中全局事务的状态选择调用try()\confirm()\cancel()
.
5. 上述就是hmily分布式事务的主体逻辑
6. 资源启动类HmilyApplicationContextAware
HmilyApplicationContextAware
public class HmilyApplicationContextAware implements ApplicationContextAware {
@Override
public void setApplicationContext(@NonNull final ApplicationContext applicationContext) throws BeansException {
// ApplicationContext设置到SpringBeanUtils中
SpringBeanUtils.INSTANCE.setCfgContext((ConfigurableApplicationContext) applicationContext);
// SpringBeanProvide设置到SingletonHolder.SINGLES存储
SingletonHolder.INST.register(ObjectProvide.class, new SpringBeanProvide());
// 应用启动
HmilyBootstrap.getInstance().start();
}
}
HmilyBootstrap
public void start() {
try {
// 加载配置保存到ConfigEnv中
ConfigLoaderServer.load();
// 获取配置类
HmilyConfig hmilyConfig = ConfigEnv.getInstance().getConfig(HmilyConfig.class);
// 校验是否配置了appName
check(hmilyConfig);
// 前面已经设置了SpringBeanProvide,所以不会设置ReflectObject
registerProvide();
// 加载事务日志存储操作实现类,并存储到HmilyRepositoryFacade
loadHmilyRepository(hmilyConfig);
// 保存到HmilyShutdownHook中,当应用关闭时,调用这个实例的close()
registerAutoCloseable(new HmilyTransactionSelfRecoveryScheduled(), HmilyRepositoryEventPublisher.getInstance());
// 指标初始化
initMetrics();
} catch (Exception e) {
LOGGER.error(" hmily init exception:", e);
System.exit(0);
}
// 打印logo
new HmilyLogo().logo();
}
private void loadHmilyRepository(final HmilyConfig hmilyConfig) {
// 通过SPI机制获取HmilySerializer和HmilyRepository实现类
HmilySerializer hmilySerializer = ExtensionLoaderFactory.load(HmilySerializer.class, hmilyConfig.getSerializer());
HmilyRepository hmilyRepository = ExtensionLoaderFactory.load(HmilyRepository.class, hmilyConfig.getRepository());
hmilyRepository.setSerializer(hmilySerializer);
// 初始化HmilyRepository
hmilyRepository.init(buildAppName(hmilyConfig));
// HmilyRepository设置到HmilyRepositoryFacade做为属性
HmilyRepositoryFacade.getInstance().setHmilyRepository(hmilyRepository);
}
hmily的资源启动类主要做:
- 加载配置;
- 通过SPI机制将事务日志存储实现类设置到HmilyRepositoryFacade;
7. RPC接口实例存储RefererAnnotationBeanPostProcessor
RefererAnnotationBeanPostProcessor
:通过SPI机制找到AnnotationField
实现类,将通过条件的字段保存到SingletonHolder
private static AnnotationField annotationField;
static {
annotationField = Optional.ofNullable(ExtensionLoaderFactory.load(AnnotationField.class)).orElse(new DefaultAnnotationField());
}
@Override
public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
Class<?> clazz = bean.getClass();
if (isProxyBean(bean)) {
clazz = AopUtils.getTargetClass(bean);
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
// 字段中是否带有@Reference注解
if (annotationField.check(field)) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object ref = field.get(bean);
Class<?> refClass = field.getType();
Method[] methods = refClass.getMethods();
boolean anyMatch = Stream.of(methods).anyMatch(method -> Objects.nonNull(method.getAnnotation(Hmily.class)));
if (anyMatch) {
// 带有Hmily注解的字段实例保存到SingletonHolder.SINGLES
SingletonHolder.INST.register(field.getType(), ref);
}
}
} catch (Exception e) {
throw new BeanInitializationException("Failed to init spring bean at filed " + field.getName()
+ " in class " + bean.getClass().getName(), e);
}
}
return bean;
}
DubboRefererAnnotationField
:AnnotationField在Apche Dubbo的实现类
@HmilySPI(value = "dubbo")
public class DubboRefererAnnotationField implements AnnotationField {
@Override
public boolean check(final Field field) {
Reference reference = field.getAnnotation(Reference.class);
return reference != null;
}
}
8. 事务日志存储
在事务状态变更,创建事务参与者等操作中,都有涉及到HmilyRepositoryStorage
。该类的功能是发送事务日志事件,异步消费日志进行对应的存储。这里存储以MySQL
,事件以创建全局事务为例
HmilyRepositoryStorage.createHmilyTransaction()
private static final HmilyRepositoryEventPublisher PUBLISHER = HmilyRepositoryEventPublisher.getInstance();
/**
* Create hmily transaction.
*/
public static void createHmilyTransaction(final HmilyTransaction hmilyTransaction) {
if (Objects.nonNull(hmilyTransaction)) {
PUBLISHER.publishEvent(hmilyTransaction, EventTypeEnum.CREATE_HMILY_TRANSACTION.getCode());
}
}
HmilyRepositoryEventPublisher.publishEvent()
private DisruptorProviderManage<HmilyRepositoryEvent> disruptorProviderManage;
public void publishEvent(final HmilyTransaction hmilyTransaction, final int type) {
// 构建事件消息载体
HmilyRepositoryEvent event = new HmilyRepositoryEvent();
event.setType(type);
event.setHmilyTransaction(hmilyTransaction);
event.setTransId(hmilyTransaction.getTransId());
// 推送事件到disruptor
push(event);
}
private void push(final HmilyRepositoryEvent event) {
// 默认异步执行
if (Objects.nonNull(hmilyConfig) && hmilyConfig.isAsyncRepository()) {
disruptorProviderManage.getProvider().onData(event);
} else {
HmilyRepositoryDispatcher.getInstance().doDispatcher(event);
}
}
DisruptorProvider<T>.onData()
public void onData(final T t) {
long position = ringBuffer.next();
try {
DataEvent<T> de = ringBuffer.get(position);
de.setT(t);
ringBuffer.publish(position);
} catch (Exception ex) {
logger.error("push data error:", ex);
}
}
有了disruptor
事件,生产者,还差消费者
DisruptorConsumer<T>
实现disruptor框架的WorkHandler
接口,做为一个代理类,实际处理交由DisruptorConsumerFactory.executor()
执行
DisruptorConsumer
public class DisruptorConsumer<T> implements WorkHandler<DataEvent<T>> {
private DisruptorConsumerFactory<T> factory;
DisruptorConsumer(final DisruptorConsumerFactory<T> factory) {
this.factory = factory;
}
@Override
public void onEvent(final DataEvent<T> t) {
if (t != null) {
factory.create().executor(t.getT());
}
}
}
HmilyRepositoryDataHandler.executor()
:通过负载均衡算法选择线程,执行HmilyRepositoryDispatcher.doDispatcher()
public void executor(final HmilyRepositoryEvent event) {
Long transId = event.getTransId();
executor.select(String.valueOf(transId)).execute(() -> {
HmilyRepositoryDispatcher.getInstance().doDispatcher(event);
event.clear();
});
}
HmilyRepositoryDispatcher.doDispatcher()
:通过事件类型,调用日志存储类执行相应操作
public void doDispatcher(final HmilyRepositoryEvent event) {
EventTypeEnum eventTypeEnum = EventTypeEnum.buildByCode(event.getType());
HmilyTransaction hmilyTransaction = event.getHmilyTransaction();
HmilyParticipant hmilyParticipant = event.getHmilyParticipant();
HmilyParticipantUndo hmilyParticipantUndo = event.getHmilyParticipantUndo();
switch (eventTypeEnum) {
case CREATE_HMILY_TRANSACTION:
HmilyRepositoryFacade.getInstance().createHmilyTransaction(event.getHmilyTransaction());
break;
case REMOVE_HMILY_TRANSACTION:
HmilyRepositoryFacade.getInstance().removeHmilyTransaction(hmilyTransaction.getTransId());
break;
case UPDATE_HMILY_TRANSACTION_STATUS:
HmilyRepositoryFacade.getInstance().updateHmilyTransactionStatus(hmilyTransaction.getTransId(), hmilyTransaction.getStatus());
break;
case CREATE_HMILY_PARTICIPANT:
HmilyRepositoryFacade.getInstance().createHmilyParticipant(event.getHmilyParticipant());
break;
case UPDATE_HMILY_PARTICIPANT_STATUS:
HmilyRepositoryFacade.getInstance().updateHmilyParticipantStatus(hmilyParticipant.getParticipantId(), hmilyParticipant.getStatus());
break;
case REMOVE_HMILY_PARTICIPANT:
HmilyRepositoryFacade.getInstance().removeHmilyParticipant(hmilyParticipant.getParticipantId());
break;
case CREATE_HMILY_PARTICIPANT_UNDO:
HmilyRepositoryFacade.getInstance().createHmilyParticipantUndo(hmilyParticipantUndo);
break;
case REMOVE_HMILY_PARTICIPANT_UNDO:
HmilyRepositoryFacade.getInstance().removeHmilyParticipantUndo(hmilyParticipantUndo.getUndoId());
break;
default:
break;
}
}
HmilyRepositoryFacade
:日志存储门面,由HmilyRepository
具体执行,而在资源启动类(HmilyBootstrap)中通过SPI机制将HmilyRepository
的实现类set进去了
HmilyRepositoryFacade.createHmilyTransaction()
/**
*创建事务
*/
public void createHmilyTransaction(final HmilyTransaction hmilyTransaction) {
checkRows(hmilyRepository.createHmilyTransaction(hmilyTransaction));
}
以MySQL
存储为例,实现类为AbstractHmilyDatabase
AbstractHmilyDatabase.createHmilyTransaction()
/**
* The constant INSERT_HMILY_TRANSACTION.
*/
protected static final String INSERT_HMILY_TRANSACTION = "INSERT INTO hmily_transaction_global (trans_id, app_name, status, trans_type, "
+ "retry, version, create_time, update_time) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
@Override
public int createHmilyTransaction(final HmilyTransaction hmilyTransaction) {
return executeUpdate(INSERT_HMILY_TRANSACTION, hmilyTransaction.getTransId(), appName, hmilyTransaction.getStatus(),
hmilyTransaction.getTransType(), hmilyTransaction.getRetry(), hmilyTransaction.getVersion(), hmilyTransaction.getCreateTime(), hmilyTransaction.getUpdateTime());
}
private int executeUpdate(final String sql, final Object... params) {
try (Connection con = dataSource.getConnection();
PreparedStatement ps = createPreparedStatement(con, sql, params)) {
return ps.executeUpdate();
} catch (SQLException e) {
log.error("hmily jdbc executeUpdate repository exception -> ", e);
return FAIL_ROWS;
}
}
4.总结
上述通过源码分析了hmily
分布式事务的主体流程,没有对源码设计进行详细分析,其中涉及很多的设计模式、SPI机制等好的设计。在接下来的文章中进行分析。
世界那么大,感谢遇见,未来可期…
欢迎同频共振的那一部分人
Tarzan写bug