云计算百科
云计算领域专业知识百科平台

【电商项目】新手CRUD踩坑记录与问题复盘——修改

在进行修改测试的时候报了个大长错。这里就不全贴在这里了因为太长了,我提取了所有主要信息供参考:

1. 顶层调用异常:

org.apache.dubbo.rpc.RpcException: Failed to invoke the method updateAdminRole in the service com.moriha.common.service.AdminService. Tried 3 times of the providers [192.168.126.1:20882] (1/1)
from the registry 192.168.0.99:8848 on the consumer 192.168.126.1 using the dubbo version 3.2.4.
Last error is: Failed to invoke remote method: updateAdminRole

2. 中间包装异常

Caused by: org.apache.dubbo.remoting.RemotingException: java.io.IOException: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: autotype not support : org.springframework.jdbc.UncategorizedSQLException

3. 根因异常

Caused by: com.alibaba.fastjson2.JSONException: autotype not support : org.springframework.jdbc.UncategorizedSQLException

报错解释:

  • RpcException: Failed to invoke the method updateAdminRole Dubbo 消费者调用远程接口updateAdminRole方法失败,已重试 3 次服务提供者依旧失败。
  • RemotingException Dubbo 网络通信层出现异常,服务端向客户端回传数据时 IO 异常。
  • SerializationException Dubbo 序列化环节出错,使用 FastJson2 序列化数据失败。
  • fastjson2.JSONException: autotype not support : UncategorizedSQLException FastJson2 默认关闭自动类型解析(autotype)安全机制,无法对 Spring 数据库通用异常UncategorizedSQLException进行序列化、反序列化;服务端数据库报错后,异常实例无法序列化传回调用方,直接打断 RPC 调用。

这个的意思总结一下就是:【提供者端(shopping_admin_service)执行 SQL 时抛出了 UncategorizedSQLException,然后 Dubbo 尝试用 fastjson2 序列化这个异常对象时失败了。】

核心字段: UncategorizedSQLException 是 Spring 对 MyBatis、JDBC 所有无法归类的数据库底层异常的统一封装类,只要出现这个异常类名,就代表服务端 SQL 执行、数据库操作直接报错了。

层级关系: 数据库 SQL 异常→抛出 UncategorizedSQLException→FastJson2 无法序列化该异常→触发 SerializationException 序列化异常→产生 RemotingException 网络 IO 返回异常→最终外层包装 RpcException 远程调用失败。

所以可以想到产生的原因大概是:

  • 业务方法内部 SQL 执行出错,数据库抛出异常,产生 UncategorizedSQLException 异常对象;
  • 其他该异常连锁传导后的衍生异常。
    • Dubbo 选用 FastJson2 做序列化,未开启 autotype 白名单,复杂异常类无法序列化传输;
    • 服务端异常序列化失败,网络响应数据构造失败,触发 Dubbo 底层 RemotingException 通信异常;
    • 远程接口多次重试依旧无法正常返回结果,Dubbo 外层包装为 RpcException 调用失败异常。

    根因是 SQL 参数错误抛出数据库异常,才触发序列化失败

    经过我的排查发现:

    我写的 addRoleToAdmin 方法的参数是 Long[] rids(数组),但 XML 中直接用了 #{rid}

    XML 未使用 foreach 遍历直接取值,SQL 参数绑定错误触发数据库异常,进而连锁引发 2、3、4 号上层框架异常。

    我没有实现数组遍历导致了这个报错。为了更直观好理解,我把问题代码粘在这里:  

    // … existing code …
    //给管理员添加角色 (我写成了Long[] rids 而非现在这样)
    void addRoleToAdmin(@Param("aid") Long aid, @Param("rid") Long rid);
    }
    // … existing code …
    @Override
    public void updateAdminRole(Long aid, Long[] rids) {
    // 删除管理员所有角色
    adminMapper.deleteAdminAllRole(aid);
    // 重新添加管理员角色
    for (Long rid : rids) {
    // 因为刚才的失误,这里允许写成 new Long[] rids
    adminMapper.addRoleToAdmin(aid, rid);
    }
    }
    // … existing code …

    改动说明:

    • AdminMapper.java:Long[] rids → Long rid,改为接收单个角色 ID
    • AdminServiceImpl.java:new Long[]{rid} → rid,循环中直接传单个值

    这样 XML 中的 #{rid} 就能正确绑定到单个 Long 值了,SQL 不再报错。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【电商项目】新手CRUD踩坑记录与问题复盘——修改
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!