tx-lcn icon indicating copy to clipboard operation
tx-lcn copied to clipboard

咨询下,tx-manager 能看到注册上的两个tc,但是exception表里没有任何数据是啥原因?自然也不能回滚

Open insight1989 opened this issue 6 years ago • 15 comments

  • [ ] I have searched the issues of this repository and believe that this is not a duplicate.

1. Bug Description

咨询下,spring cloud框架 feign远程调用。 tx-manager 能看到注册上的两个tc,但是exception表里没有任何数据是啥原因?自然也不能回滚,A 代码中 访问B服务.然后手动写死抛出一个RuntimeException的子类,然后B服务数据没回滚可咋整 。 在线等。今天解决不了就得回家烤红薯为生了。

2. Environment:

  • JDK version: 1.8
  • OS: Ubuntu
  • TX-LCN version: 5.0.2.RELEASE
  • Others:

3. Exception Stacktrace

Paste your Exception Stacktrace here!

4. Tour Idea

insight1989 avatar Dec 16 '19 06:12 insight1989

看抛出的异常中都能看到经过了com.codingapi.txlcn.tc.aspect.weave.DTXLogicWeaver.runTransaction,就是插入的数据没被删掉。。这个,我都想哭了。。可咋整。

insight1989 avatar Dec 16 '19 06:12 insight1989

代码咋写的

yizhishang avatar Dec 16 '19 06:12 yizhishang

代码咋写的

`@LcnTransaction //分布式事务注解
@Transactional
@Override
public boolean create(OrganizationVo organization) throws BusinessException{

    if (null!=this.getOne(new QueryWrapper<Organization>().eq("org_no", organization.getOrgNo()))) {
        throw new BusinessException("机构编号不能与存在的重复");
    }
    if (StringUtils.isEmpty(organization.getOrgNo())) {
        Integer type = organization.getOrgType();
        organization.setOrgNo("KLT-"+type +"-"+ DateUtil.format(new Date(),"yyyymmdd")+ org.apache.commons.lang3.StringUtils.leftPad(""+RandomUtil.randomInt(0,100),6));
    }

    boolean ok = this.save(organization);
    if (ok) {
        if (organization.getCommissionRate() != null && StringUtils.isNotEmpty(organization.getSettlementCycle())) {
            //存储分成比例和结算周期
            FinanceRules financeRules = new FinanceRules();
            financeRules.setIsDefault(1);
            financeRules.setOrganizationId(organization.getId());
            financeRules.setServiceChargeRatio(organization.getCommissionRate());
            financeRules.setSettlementPeriod(organization.getSettlementCycle());
            financeRules.setOrganizationName(organization.getName());
            financeRules.setStatus(1);
            R r = financeRulesFeignClient.create(financeRules);
            r.setSuccess(false);
            if (r.isSuccess()) {
                return true;
            } else {
                throw new BusinessException("远程调用保存结算周期失败");
            }
        }
    }
    return ok;
}

` financeRulesFeignClient.create(financeRules);这句是远程调用。但是我下面手动故意抛出了BusinessException,这个是RuntimeException的子类。。我想预期的结果是financeRulesFeignClient.create(financeRules);这个操作插入的记录因为异常又删掉了。。但是实际上没删掉。。 两个启动类都加了@EnableTransactionManagement @EnableDistributedTransaction @SpringCloudApplication

启动时候,debug看了DataSourceAspect 这个都可以debug进,jdbc获取Connection也是txlcn代理后的对象。有系统记录,但是没有异常日志。

另外我配置的还是,在网上找了一段配置粘贴进去了。就是下面这段:

` @Configuration @EnableTransactionManagement public class AopTypeDTXConfiguration {

/**
 * 本地事务配置
 *
 * @param transactionManager
 * @return
 */
@Bean
@ConditionalOnMissingBean
public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
    Properties properties = new Properties();
    properties.setProperty("*", "PROPAGATION_REQUIRED,-Throwable");
    TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
    transactionInterceptor.setTransactionManager(transactionManager);
    transactionInterceptor.setTransactionAttributes(properties);
    return transactionInterceptor;
}

/**
 * 分布式事务配置 设置为LCN模式
 *
 * @param dtxLogicWeaver
 * @return
 */
@ConditionalOnBean(DTXLogicWeaver.class)
@Bean
public TxLcnInterceptor txLcnInterceptor(DTXLogicWeaver dtxLogicWeaver) {
    TxLcnInterceptor txLcnInterceptor = new TxLcnInterceptor(dtxLogicWeaver);
    Properties properties = new Properties();
    properties.setProperty(Transactions.DTX_TYPE, Transactions.LCN);
    properties.setProperty(Transactions.DTX_PROPAGATION, "REQUIRED");
    txLcnInterceptor.setTransactionAttributes(properties);
    return txLcnInterceptor;
}

@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
    BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
    beanNameAutoProxyCreator.setInterceptorNames("txLcnInterceptor", "transactionInterceptor");
    beanNameAutoProxyCreator.setBeanNames("*Impl");
    return beanNameAutoProxyCreator;
}

}`

insight1989 avatar Dec 16 '19 06:12 insight1989

日志能看到两个微服务事务都添加了吗

yizhishang avatar Dec 16 '19 07:12 yizhishang

com.syc.common.api.BusinessException: 远程调用保存结算周期失败 at com.syc.product.service.impl.OrganizationServiceImpl.create(OrganizationServiceImpl.java:269) ~[classes/:?] at com.syc.product.service.impl.OrganizationServiceImpl$$FastClassBySpringCGLIB$$c3571fea.invoke() ~[classes/:?] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:750) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at com.codingapi.txlcn.tc.aspect.weave.DTXLogicWeaver.runTransaction(DTXLogicWeaver.java:57) ~[txlcn-tc-5.0.2.RELEASE.jar:5.0.2.RELEASE] at com.codingapi.txlcn.tc.aspect.TransactionAspect.runWithLcnTransaction(TransactionAspect.java:93) ~[txlcn-tc-5.0.2.RELEASE.jar:5.0.2.RELEASE] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_231] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_231] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_231] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_231] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]

这个异常中能看到经过了DTXLogicWeaver.runTransaction ,但是其他日志信息,哪个group之类,start end在 调用方没打印出来。。

insight1989 avatar Dec 16 '19 07:12 insight1989

调用链,有join in group之类的信息吗

yizhishang avatar Dec 16 '19 07:12 yizhishang

主调用方日志:

2019-12-16 15:42:37.264 | DEBUG | naming.failover | c.a.n.c.naming | 110 | run | failover switch is not found, failover00-00---000-VIPSRV_FAILOVER_SWITCH-000---00-00 2019-12-16 15:42:37.268 | DEBUG | ing.beat.sender | c.a.n.c.naming | 303 | sendBeat | [BEAT] 1eb4e299-9e15-4eed-861e-7620c908e9a5 sending beat to server: {"cluster":"DEFAULT","ip":"192.168.50.173","metadata":{"preserved.register.source":"SPRING_CLOUD"},"period":5000,"port":10087,"scheduled":false,"serviceName":"DEFAULT_GROUP@@medtrip-product","stopped":false,"weight":1.0} 2019-12-16 15:42:37.269 | DEBUG | ing.beat.sender | c.a.n.c.naming | 90 | request | Request from server: http://beta.nacos.sycidc.com:8848/nacos/v1/ns/instance/beat?beat=%7B%22cluster%22%3A%22DEFAULT%22%2C%22ip%22%3A%22192.168.50.173%22%2C%22metadata%22%3A%7B%22preserved.register.source%22%3A%22SPRING_CLOUD%22%7D%2C%22period%22%3A5000%2C%22port%22%3A10087%2C%22scheduled%22%3Afalse%2C%22serviceName%22%3A%22DEFAULT_GROUP%40%40medtrip-product%22%2C%22stopped%22%3Afalse%2C%22weight%22%3A1.0%7D&serviceName=DEFAULT_GROUP%40%40medtrip-product&encoding=UTF-8&namespaceId=1eb4e299-9e15-4eed-861e-7620c908e9a5 2019-12-16 15:42:37.305 | DEBUG | XNIO-2 task-1 | d.s.Connection | 132 | connectionLog | {conn 10001} rollback 2019-12-16 15:42:37.305 | DEBUG | XNIO-2 task-1 | d.s.Connection | 132 | connectionLog | {conn-10001} setAutoCommit true 2019-12-16 15:42:37.306 | DEBUG | XNIO-2 task-1 | d.s.Connection | 132 | connectionLog | {conn-10001} pool-recycle 2019-12-16 15:42:37.306 | DEBUG | XNIO-2 task-1 | c.c.t.t.c.t.l.r.LcnConnectionProxy | 54 | notify | transaction type[lcn] proxy connection:com.codingapi.txlcn.tc.core.transaction.lcn.resource.LcnConnectionProxy@646c7f8e closed. 2019-12-16 15:42:37.307 | DEBUG | XNIO-2 task-1 | c.c.t.t.c.t.TransactionCleanTemplate | 59 | trace | clean transaction over @group(6667dfd089a537) 2019-12-16 15:42:37.307 | DEBUG | XNIO-2 task-1 | c.c.t.t.c.t.TransactionControlTemplate | 59 | trace | notify group exception state 0. @group(6667dfd089a537) 2019-12-16 15:42:37.308 | DEBUG | XNIO-2 task-1 | c.c.t.t.c.c.DefaultGlobalContext | 162 | destroyTx | Destroy TxContext[6667dfd089a537] 2019-12-16 15:42:37.308 | DEBUG | ool-4-thread-12 | c.c.t.t.c.a.AsyncH2DBAspectLogger | 92 | lambda$clearLog$2 | async clear aspect log. result:true, groupId: 6667dfd089a537, used time: 1ms 2019-12-16 15:42:37.308 | DEBUG | XNIO-2 task-1 | c.c.t.t.c.DTXLocalContext | 170 | makeNeverAppeared | clean thread local[DTXLocalContext]: DTXLocalContext(transactionType=lcn, groupId=6667dfd089a537, unitId=b3b7c01a31a68fdaf4c40dd811c1b734, resource=null, destroy=true, inGroup=false, attachment=null, sysTransactionState=0, userTransactionState=-1, proxy=true, justNow=false, proxyTmp=false) 2019-12-16 15:42:37.308 | DEBUG | XNIO-2 task-1 | c.c.t.t.a.w.DTXLogicWeaver | 113 | runTransaction | <---- TxLcn end ---->

insight1989 avatar Dec 16 '19 07:12 insight1989

调用链,有join in group之类的信息吗

没有,都是简单的mybatisplus 单表插入数据操作。

insight1989 avatar Dec 16 '19 07:12 insight1989

那就不应该了

yizhishang avatar Dec 16 '19 07:12 yizhishang

去掉@Transactional 这个 然后,将这个AopTypeDTXConfiguration配置类 干掉 再试试

yizhishang avatar Dec 16 '19 07:12 yizhishang

去掉@transactional 这个 然后,将这个AopTypeDTXConfiguration配置类 干掉 再试试

我说明下,我是methodA()方法,自己先mapper插入一条记录,然后远程调用服务B插入一条记录,然后在methodA中故意抛了个异常,要把服务B插入的记录删掉。 我把AopTypeDTXConfiguration 在微服务中都删掉了,在调用方,把@Transaction删掉了,我感觉是调用方遇到异常后,再没通知让B回滚,B啥都不知道。。就是遇到这个异常为什么没在tx_exception插入记录。。这感觉断链子了。。

insight1989 avatar Dec 16 '19 08:12 insight1989

tm中有有这个tx-client的注册信息吗

yizhishang avatar Dec 16 '19 08:12 yizhishang

2019-12-16 16:09:29.180 | DEBUG | XNIO-2 task-2 | c.c.t.t.c.t.TransactionControlTemplate | 59 | trace | notify group exception state 1. @group(6669657d19c537) 被调用方,这句日志说的是执行回滚了吗? 但是数据还在,用的是mysql 8, 数据库上有什么要求吗

insight1989 avatar Dec 16 '19 08:12 insight1989

tm中有有这个tx-client的注册信息吗 两个都有。

insight1989 avatar Dec 16 '19 08:12 insight1989

数据库应该没多大差别,不过mysql8貌似问题很多,业内用的比较多的还是5.7.28

yizhishang avatar Dec 16 '19 08:12 yizhishang