⚡ 金蝶全票池定时同步按变更比对落库并加 single-flight 锁

- 镜像批量 upsert 增加票面字段指纹比对,票面无变化不重写(含 attachments_json 大字段),口径对齐 MyBatis-Plus 非空字段更新策略
- 收票登记绑定前比对 kingdeeInvoicePoolId/kingdeeBillNo/kingdeeStatus,三项均无变化不更新;同步流水只在绑定关系变化或金蝶状态迁移时写入,原因文案按语义拆分为「定时绑定」与「定时刷新」
- 同步入口按租户加 RedisLockClient 分布式锁做 single-flight(零等待、租约可配 lockLeaseSeconds),未开启 blade.lock.enabled 时降级执行并告警
- 客商税号白名单明确为购、销双方税号均须命中客商档案(我方主体税号亦在档案中),抽出 taxNoArchived 做空值防护
- 日志补强:每页过滤漏斗明细、镜像无变化数、镜像未匹配登记提示、翻页触顶告警、补偿绑定耗时与远程补查次数、解析失败带发票号码
- Nacos 模板:MySQL 连接串补 rewriteBatchedStatements=true 使 JDBC 批量真正合批;dev/test 开启 blade.lock.enabled,prod 补开启前置条件说明
- SyncKingdeeTest:方法名更正为 syncKingdeeInvoicePool,测试属性关闭 syncEnabled,避免 cron 与手动触发在同一 JVM 并发跑
This commit is contained in:
刘泉佳
2026-09-21 17:31:22 +08:00
parent 9a82ed2eaf
commit b3eee6347b
7 changed files with 363 additions and 75 deletions
+4 -2
View File
@@ -32,7 +32,8 @@ spring:
blade:
#分布式锁配置
lock:
enabled: false
# blade.lock.enabled=true 才会装配 RedisLockClient;收票全票池同步等定时任务依赖它做 single-flight
enabled: true
address: redis://127.0.0.1:6379
#多团队协作服务配置
loadbalancer:
@@ -46,7 +47,8 @@ blade:
datasource:
dev:
# MySql
url: jdbc:mysql://localhost:3306/transport?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
# rewriteBatchedStatements=true:MyBatis-Plus saveBatch/updateBatchById 依赖该参数才会合并为多值语句,否则仍是逐条往返(仅 MySQL 支持,切换其他库需移除)
url: jdbc:mysql://localhost:3306/transport?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
username: root
password: root
# PostgreSQL
+4 -1
View File
@@ -35,14 +35,17 @@ blade:
#分布式锁配置
lock:
##是否启用分布式锁
##开启前必须先补 password(与 spring.data.redis 一致),否则 Redisson 无密码连接会被拒绝,
##影响的是全部依赖该模板的服务;收票全票池等同步定时任务依赖它做多副本 single-flight
enabled: false
#password:
##将docker脚本部署的redis服务映射为宿主机ip
##生产环境推荐使用阿里云高可用redis服务并设置密码
address: redis://172.16.203.228:6379
#通用开发生产环境数据库地址(特殊情况可在对应的子工程里配置覆盖)
datasource:
prod:
url: jdbc:mysql://172.16.203.228:3306/transport?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
url: jdbc:mysql://172.16.203.228:3306/transport?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
username: transport
password: ab3acJYSC8A4ySpk
+3 -3
View File
@@ -33,14 +33,14 @@ spring:
blade:
#分布式锁配置
lock:
##是否启用分布式锁
enabled: false
##是否启用分布式锁(收票全票池同步等定时任务依赖 RedisLockClient 做 single-flight,多副本部署必须开启)
enabled: true
##将docker脚本部署的redis服务映射为宿主机ip
address: redis://192.168.0.188:3379
#通用开发生产环境数据库地址(特殊情况可在对应的子工程里配置覆盖)
datasource:
test:
url: jdbc:mysql://192.168.0.188:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
url: jdbc:mysql://192.168.0.188:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true
username: root
password: root