Giter Site home page Giter Site logo

hmily's Introduction

Financial-level flexible distributed transaction solution

https://dromara.org/

English | 简体中文

gitee stars github forks github stars github contributors



Panorama of distributed transaction solutions


Features

  • high reliability :supports abnormal transaction rollback in distributed scenarios, and abnormal recovery over time to prevent transaction suspension

  • usability :provide zero-invasive Spring-Boot, Spring-Namespace to quickly integrate with business systems

  • high performance :decentralized design, fully integrated with business systems, naturally supporting cluster deployment

  • observability :metrics performance monitoring of multiple indicators, and admin management background UI display

  • various RPC : support Dubbo, SpringCloud, Motan, Sofa-rpc, brpc, tars and other well-known RPC frameworks

  • log storage : support mysql, oracle, mongodb, redis, zookeeper etc.

  • complex scene : support RPC nested call transaction


Necessary premise

  • must use JDK8+

  • TCC mode must use a RPC framework, such as: Dubbo, SpringCloud, Montan


TCC mode

when using the TCC mode, users provide three methods: try, confirm, and cancel according to their business needs. And the confirm and cancel methods are implemented by themselves, and the framework is only responsible for calling them to achieve transaction consistency。


TAC mode

When the user uses the TAC mode, the user must use a relational database for business operations, and the framework will automatically generate a rollback SQL, When the business is abnormal, the rollback SQL will be executed to achieve transaction consistency。


Documentation

EN doc

CN doc

If you want to use it, you can refer to Quick Start

About Hmily

Hmily is a flexible distributed transaction solution that provides TCC and TAC modes。

It can be easily integrated by business with zero intrusion and rapid integration。

In terms of performance, log storage is asynchronous (optional) and asynchronous execution is used, without loss of business methods。

It was previously developed by me personally. At present, I have restarted at JD Digital. The future will be a distributed transaction solution for financial scenarios.。


Follow the trend

Stargazers over time


User wall

Support

hmily's People

Contributors

bbaiggey avatar cchenxi avatar cedar-gao avatar cherrylzhao avatar choviwu avatar codacy-badger avatar cysy-lli avatar dengliming avatar dependabot[bot] avatar dongzl avatar fattyca1 avatar fjz99 avatar god8816 avatar idefav avatar jilonghun avatar kissss avatar li-xiao-shuang avatar liuyueve avatar peiht avatar photowey avatar prfor avatar supermario1990 avatar tuohai666 avatar tydhot avatar whyhe avatar xenosxia avatar xqxyxchy avatar yu199195 avatar zkyoma avatar zwjzhangwanjie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hmily's Issues

压测数据一致性问题

我用jmeter压测了一下并发100,2万条数据
a远程调用b,测试confirm逻辑,a,b各自在自己表中插入一条记录
最终a服务的表插入17769条 ,b服务的表插入18581条, a,b服务达到一致性记录数有16496条
也就是有一些回滚了,现在我不知道是我的代码问题,还是其他原因
a服务代码
1
服务配置
1c

b服务代码
2
b服务配置
2c

请教大佬!!!!

关于超时的cancel调用

有一个问题请教一下

假设有个服务A 需要依次调用 服务B,C
如果A->B 成功了,A->C 超时了,但是实际A->C 调用成功了

那么A->B 会进行cancel操作,但是C因为失败了,所以A没有把C 加入到参与者队列,没有给他发cancel请求,那C的cancel操作是否会执行?什么时候执行?

线程并发问题

5个线程,每隔100ms执行一次支付接口,出现金额为负数,此时调用账号扣款服务全部开始报错。

qq 20181116112342

错误如下:
java.lang.reflect.InvocationTargetException: null
at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.apache.commons.lang3.reflect.MethodUtils.invokeMethod(MethodUtils.java:132) ~[commons-lang3-3.3.2.jar:3.3.2]
at com.hmily.tcc.core.service.executor.HmilyTransactionExecutor.executeParticipantMethod(HmilyTransactionExecutor.java:309) ~[classes/:na]
at com.hmily.tcc.core.service.executor.HmilyTransactionExecutor.confirm(HmilyTransactionExecutor.java:222) ~[classes/:na]
at com.hmily.tcc.core.service.handler.ParticipantHmilyTransactionHandler.handler(ParticipantHmilyTransactionHandler.java:73) [classes/:na]
at com.hmily.tcc.core.service.impl.HmilyTransactionAspectServiceImpl.invoke(HmilyTransactionAspectServiceImpl.java:58) [classes/:na]
at com.hmily.tcc.springcloud.interceptor.SpringCloudHmilyTransactionInterceptor.interceptor(SpringCloudHmilyTransactionInterceptor.java:83) [classes/:na]
at com.hmily.tcc.core.interceptor.AbstractTccTransactionAspect.interceptTccMethod(AbstractTccTransactionAspect.java:53) [classes/:na]
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at com.hmily.tcc.demo.springcloud.account.service.impl.AccountServiceImpl$$EnhancerBySpringCGLIB$$1928bc5e.payment() [classes/:na]
at com.hmily.tcc.demo.springcloud.account.controller.AccountController.save(AccountController.java:48) [classes/:na]
at sun.reflect.GeneratedMethodAccessor65.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar:8.5.31]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: com.hmily.tcc.common.exception.TccRuntimeException: 确认扣减账户异常!
at com.hmily.tcc.demo.springcloud.account.service.impl.AccountServiceImpl.confirm(AccountServiceImpl.java:108) ~[classes/:na]
at com.hmily.tcc.demo.springcloud.account.service.impl.AccountServiceImpl$$FastClassBySpringCGLIB$$9c973d2f.invoke() ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) [spring-aop-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at com.hmily.tcc.demo.springcloud.account.service.impl.AccountServiceImpl$$EnhancerBySpringCGLIB$$1928bc5e.confirm() [classes/:na]
... 73 common frames omitted

事务日志采用异步写入导致无法回滚

"采用disruptor框架进行事务日志的异步读写,与RPC框架的性能毫无差别。"
事务日志采用异步写入,如果事务日志本身插入失败,是否就无法走回滚流程了

超时异常是怎么处理?

1.看到代码在异常时未判断是超时异常或者乐观锁异常。直接进行cancel处理,有可能被调用方的try方法还在执行的情况。这样不是会有问题?

springcloud的demo中InventoryServiceImpl的confirmMethodTimeout,confirmMethodException两个方法的作用?

    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmMethodTimeout(InventoryDTO inventoryDTO) {
        try {
            //模拟延迟 当前线程暂停11秒
            Thread.sleep(11000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LOGGER.info("==========Springcloud调用扣减库存确认方法===========");
        final InventoryDO entity = inventoryMapper.findByProductId(inventoryDTO.getProductId());
        entity.setLockInventory(entity.getLockInventory() - inventoryDTO.getCount());
        inventoryMapper.decrease(entity);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmMethodException(InventoryDTO inventoryDTO) {
        LOGGER.info("==========Springcloud调用扣减库存确认方法===========");
        final InventoryDO entity = inventoryMapper.findByProductId(inventoryDTO.getProductId());
        entity.setLockInventory(entity.getLockInventory() - inventoryDTO.getCount());
        final int decrease = inventoryMapper.decrease(entity);
        if (decrease != 1) {
            throw new TccRuntimeException("库存不足");
        }
        return true;
        // throw new TccRuntimeException("库存扣减确认异常!");
    }

没看懂InventoryServiceImpl的这两个地方,在哪里有用到

多层调用是否支持

1、例如A->B->C这种层级调用是否已经支持了?
2、同一接口中实现 A->B1,A->B2 调用支持吗?

springcloud内嵌事物

在请求模型中
ui->a->b-c
b无法使用内嵌事物,导致b c 的cancelMethod confirmMethod 都无法执行完全

java.lang.Object cannot be cast to XXX

如果AccountService的payment方法返回值是个对象,如
AccountDTO payment(AccountDTO accountDTO);

执行cancel的时候会报错如下:

2018-10-23 18:22:02.388 ERROR 10427 --- [:20884-thread-3] c.a.dubbo.rpc.filter.ExceptionFilter : [DUBBO] Got unchecked and undeclared exception which called by 172.16.3.41. service: com.hmily.tcc.demo.dubbo.account.api.service.AccountService, method: payment, exception: java.lang.ClassCastException: java.lang.Object cannot be cast to com.hmily.tcc.demo.dubbo.account.api.dto.AccountDTO, dubbo version: 2.6.2, current host: 172.16.3.46

java.lang.ClassCastException: java.lang.Object cannot be cast to com.hmily.tcc.demo.dubbo.account.api.dto.AccountDTO
at com.hmily.tcc.demo.dubbo.account.service.AccountServiceImpl$$EnhancerBySpringCGLIB$$2e89faa6.payment() ~[classes/:na]
at com.alibaba.dubbo.common.bytecode.Wrapper1.invokeMethod(Wrapper1.java) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:76) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:52) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.rpc.filter.AccessLogFilter.invoke(AccessLogFilter.java:155) ~[dubbo-2.6.2.jar:2.6.2]
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:72) [dubbo-2.6.2.jar:2.6.2]
......

`

集群模式下定时恢复问题

这里假设是发起者发起重试confirm,此时我有发起者的集群,这时他们都会去发起重试,虽然代码里有乐观锁机制保证了最大重试次数,但是如果机器A修改retrycount后,发起confirm,机器B仅跟着修改retrycount,发起confirm。
若业务没有幂等处理,这样就会导致confirm执行两次,所以需要用户保证业务的confirm和cancel的幂等吧?

关于demo中库存量回滚

1.模拟下单付款操作在try阶段超时异常,此时账户系统和订单状态会回滚,但库存量不回滚,达到数据的一致性(异常指的是超时异常),这种情况下库存量不回滚了是因为库存量最终还是扣除了。
2.模拟下单付款操作在try阶段异常,此时账户系统和订单状态会回滚,但库存量回滚,达到数据的一致性(注意:这里模拟的是系统异常,或者rpc异常),这种情况是触发了本地数据库事务回滚,是这个原因么?谢谢!

spring cloud 2.0

请问一下现在支持spring-boot 2.0 或者说spring 5.0么,我看demo用的是1.5.9

facade接口使用有问题

java.lang.NoSuchMethodException: com.qlbt.facade.member.HomeWorkFacade.$echo(java.lang.String)
at java.lang.Class.getMethod(Class.java:1786)
at org.dromara.hmily.dubbo.filter.DubboHmilyTransactionFilter.invoke(DubboHmilyTransactionFilter.java:75)
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:74)
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
at com.alibaba.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:53)
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
at com.alibaba.dubbo.rpc.filter.ConsumerContextFilter.invoke(ConsumerContextFilter.java:47)
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
at com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:73)

重试机制实现疑问

如果confirm阶段,部分下游成功,部分下游失败,这时为啥选择重试失败的,而不是回滚成功的?
比如库存场景,try阶段库存没问题,但在confirm阶段锁库存失败,因为被别的线程已经锁定成功了。

创建tcc库的表发生异常

运行springcloud demo时

2018-10-11 13:53:09.335 ERROR 23152 --- [ main] c.h.t.c.s.r.JdbcCoordinatorRepository : executeUpdate-> CREATE command denied to user 'dev'@'115.236.92.180' for table 'tcc_account_service'

tcc 库 我没有创建表的功能 但是这边返回的是 dev'@'115.236.92.180 我实际的ip是118.178.195.63 不知道为什么变成了 'dev'@'115.236.92.180'

confirm失败没有回滚

dubbo的demo中mockInventoryWithConfirmExceptionmockInventoryWithConfirmTimeout两个方法被注释掉了,而且通过这两个方法调用发现在confirn阶段发生异常没有调用cancel逻辑

关于服务分布式部署后事物回滚的问题

目前看代码结构,于每个依赖tcc的项目都会引入hmily-core包,该包中的回滚定时任务一直在执行。

我有个疑惑
假设:账户服务分布式部署(account-service-a,account-service-b),发起了一笔交易并且账户服务产生了异常。那么,两个账户服务是否会分别发起一次回滚请求,也就相当于发起两次回滚请求?

Dubbo User Guide 中 <version>{you version}<version> 没有闭合

在你的接口项目中引入jar包,并在需要参与Tcc分布式事务的接口方法上添加@tcc注解。

com.happylifeplat.tcc
happylifeplat-tcc-annotation
{you version}

在你的实现项目中引入jar包,并在实现接口上添加: @tcc(confirmMethod = "confirm", cancelMethod = "cancel")confirmMethod,cancelMethod对应为的方法名称

com.happylifeplat.tcc
happylifeplat-tcc-dubbo
{you version}

TCC各阶段对应操作是否不合理?

T-Try预留资源,demo中对应是锁库存、冻结资金;
C-Confirm确认执行业务,demo中是减库存、减资金--真正的业务方法(即添加TCC注解的方法才是业务);
C-Cancel业务回滚,demo中是解锁库存、解冻资金;

但在框架中对应却不是这样的,真正的业务在框架处理时对应的是T-Try操作;
hmily

是我理解错误么?
求解惑。

com.hmily.tcc.common.bean.entity.Participant转换错误

有人遇到过这种情况吗?

2018-12-19 16:00:36.044 [hmilyTransaction-tccRollBackService-1] ERROR com.hmily.tcc.core.schedule.ScheduledService - execute recover exception:com.hmily.tcc.common.bean.entity.Participant cannot be cast to com.hmily.tcc.common.bean.entity.Participant
java.lang.ClassCastException: com.hmily.tcc.common.bean.entity.Participant cannot be cast to com.hmily.tcc.common.bean.entity.Participant
at com.hmily.tcc.core.schedule.ScheduledService.cancel(ScheduledService.java:135)
at com.hmily.tcc.core.schedule.ScheduledService.lambda$0(ScheduledService.java:113)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

tcc业务同时只能执行一个吗?

StartTccTransactionHandler.handler这里使用了LOCK.lock();同一时刻只能执行一个tcc业务吗?如果这个时候正在执行的tcc业务出现超时,其他的tcc业务是不是会一直阻塞?这种情况怎么优化;

代码好像有点问题

public TccTransaction findById(String id) {
try {

        final String redisKey = RepositoryPathUtils.buildRedisKey(keyPrefix, id);
        byte[] contents = jedisClient.get(redisKey.getBytes());
       //contents可能为空,好像代码中缺少判断
        if(contents == null) 
        	return null;
        return RepositoryConvertUtils.transformBean(contents, objectSerializer);
    } catch (Exception e) {
        throw new TccRuntimeException(e);
    }
}

超时异常,库存数没有回滚

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.