shardingjdbc+mybatisP+Seata 报错 throw new ShouldNeverHappenException,Failed to fetch schema of t_user

Posted LuckyWangxs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shardingjdbc+mybatisP+Seata 报错 throw new ShouldNeverHappenException,Failed to fetch schema of t_user相关的知识,希望对你有一定的参考价值。

如果是寻求解决问题的,可以划走了,我这篇帖子是询问问题的哈哈哈,实在抱歉,搞了很久没搞定,如果你是大牛 帮我看看

项目用的是SpringCloud SpringCloud alibaba + mybatis plus+druid+shardingjdbc+seata
在做分布式事务事出现的问题,每个服务对应自己的数据库,也做了分库
比如user表,以userId分库,如果不用shardingjdbc分库,seata可以正常使用,如果加上shardingjdbc分库,则报错如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Error preparing statement.  Cause: io.seata.common.exception.ShouldNeverHappenException: [xid:192.168.201.159:8091:8494064366571848511]get table meta failed, please check whether the table `t_user` exists.
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77) ~[mybatis-spring-1.3.2.jar:1.3.2]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) ~[mybatis-spring-1.3.2.jar:1.3.2]
	at com.sun.proxy.$Proxy89.insert(Unknown Source) ~[na:na]
	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278) ~[mybatis-spring-1.3.2.jar:1.3.2]
	at com.baomidou.mybatisplus.core.override.PageMapperMethod.execute(PageMapperMethod.java:68) ~[mybatis-plus-core-3.0.3.jar:na]
	at com.baomidou.mybatisplus.core.override.PageMapperProxy.invoke(PageMapperProxy.java:64) ~[mybatis-plus-core-3.0.3.jar:na]
	at com.sun.proxy.$Proxy91.addSelective(Unknown Source) ~[na:na]
	at com.single.service.impl.AccountServiceImpl.buildAndSaveUseAndMappings(AccountServiceImpl.java:321) ~[classes/:na]
	at com.single.service.impl.AccountServiceImpl.createAccount(AccountServiceImpl.java:107) ~[classes/:na]
	at com.single.service.impl.AccountServiceImpl$$FastClassBySpringCGLIB$$1c3e8fe4.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at com.single.service.impl.AccountServiceImpl$$EnhancerBySpringCGLIB$$b47de357.createAccount(<generated>) ~[classes/:na]
	at com.single.controller.AccountController.createAccount(AccountController.java:57) ~[classes/:na]
	at sun.reflect.GeneratedMethodAccessor177.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_192]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_192]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_192]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_192]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.29.jar:9.0.29]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_192]
Caused by: org.apache.ibatis.executor.ExecutorException: Error preparing statement.  Cause: io.seata.common.exception.ShouldNeverHappenException: [xid:192.168.201.159:8091:8494064366571848511]get table meta failed, please check whether the table `t_user` exists.
	at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:97) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185) ~[mybatis-3.4.6.jar:3.4.6]
	at sun.reflect.GeneratedMethodAccessor178.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_192]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_192]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ~[mybatis-spring-1.3.2.jar:1.3.2]
	... 61 common frames omitted
Caused by: io.seata.common.exception.ShouldNeverHappenException: [xid:192.168.201.159:8091:8494064366571848511]get table meta failed, please check whether the table `t_user` exists.
	at io.seata.rm.datasource.sql.struct.cache.AbstractTableMetaCache.getTableMeta(AbstractTableMetaCache.java:69) ~[seata-all-1.4.2.jar:1.4.2]
	at io.seata.rm.datasource.AbstractConnectionProxy.prepareStatement(AbstractConnectionProxy.java:115) ~[seata-all-1.4.2.jar:1.4.2]
	at sun.reflect.GeneratedMethodAccessor152.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_192]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_192]
	at org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke(ConnectionLogger.java:55) ~[mybatis-3.4.6.jar:3.4.6]
	at com.sun.proxy.$Proxy118.prepareStatement(Unknown Source) ~[na:na]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88) ~[mybatis-3.4.6.jar:3.4.6]
	... 72 common frames omitted

在网上查了很久,依旧没有找到解决方案,大部分说是由于user表没有主键,或者是用了联合主键,或者是主键没有自增,或者是使用的mybatis plus自带的插入方法,sql中不带主键字段,都尝试过了,依旧是这个问题

下面是代码:

    @Override
    @Transactional(rollbackFor = ArithmeticException.class)
    @ShardingTransactionType(TransactionType.BASE)
    public ReturnResponse<LoginRespDTO> smsLogin(LoginReqDTO reqDTO) 
        log.info("【 验证码登录入参 】", JSON.toJSON(reqDTO));
        LoginRespDTO resp = new LoginRespDTO();
        try 
            // 发送验证码后会将验证码存入redis, 5分钟有效, 在登录的时候要从redis取, 如果取时异常, rpc短信服务去mysql查
            code = RedisUtil.get(CommonConstants.CAPTCHA_REDIS_PREFIX + reqDTO.getPhone() + 3);
         catch (Exception e) 
            ReturnResponse<SmsSendRecordDTO> sendRecord = smsClient.findSendRecord(reqDTO.getPhone());
            // .....
        
        if (this.checkVerifyCode(code, resp, reqDTO.getSmsCode())) 
            log.error("【 smsLogin -> 验证码校验失败 】", JSON.toJSON(resp));
            return ReturnResponse.fail(resp);
        
        AccountReqDTO accountReqDTO = new AccountReqDTO();
        this.buildAccountReqDTO(accountReqDTO, reqDTO);
        ReturnResponse<AccountRespDTO> accountByPhone = accountClient.findAccountByPhone(accountReqDTO);
        AccountRespDTO user = accountByPhone.getData();
        long userId = -1L;
        if (user == null) 
            // 首次注册, 送积分
            ReturnResponse<AccountRespDTO> account = accountClient.createAccount(accountReqDTO);
            if (!account.isSuccess()) 
                log.error("【 smsLogin -> 用户注册失败 】", JSON.toJSON(account));
                return ReturnResponse.fail(RtnConstant.REGISTER_FAIL_CODE, RtnConstant.REGISTER_FAIL_MSG);
            
           // 注册返现逻辑省略...
            log.info("【 注册成功... 】");
         else 
            userId = user.getUserId();
        
        // 生成token
        String token = this.tokenService.createToken(userId);
        resp.setToken(token);
        resp.setLoginResult(true);
        UserContext.addRtnResultMap(resp);
        log.info("【 登录成功.. 】");
        return ReturnResponse.success(resp);
    

也写了aop把事务模式设置为BASE,当feign调用account服务创建账户时,插入分库的user表就会报最开始的异常。表有主键没有问题,不知道有了解的大神帮忙解决下不

以上是关于shardingjdbc+mybatisP+Seata 报错 throw new ShouldNeverHappenException,Failed to fetch schema of t_user的主要内容,如果未能解决你的问题,请参考以下文章

ShardingSphere技术专题「ShardingJDBC入门阶段」带你一同认识一下ShardingJDBC是什么?(高手勿入)

ShardingSpherespringboot整合shardingjdbc+mybatis进行增删改查

ShardingSphere技术专题「ShardingJDBC实战阶段」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)

ShardingJdbc相关知识

ShardingSphere技术专题ShardingJDBC实现分库分表

分库分表中间件---ShardingJdbc