共计 1829 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
在生产订单日常处理中,CO02 事务码频繁重读生产计划主数据(如 MRP 参数、工艺路线)时会出现明显性能瓶颈。我们观察到以下典型问题场景:

- 当工艺路线包含多级工序时,标准逻辑会反复读取相同的 BOM 和工艺数据
- 多人同时处理相同订单时产生重复数据库查询
- 主数据变更后存在短暂的数据不一致窗口期
直接修改 SAP 标准程序存在极大风险:
- 升级时会被覆盖,导致维护成本激增
- 可能破坏标准程序的事务完整性
- 难以通过系统合规性检查
技术方案
采用 PPORDER_UPDATE BAdI 增强点实现非侵入式改造,核心架构分为三层:
- 缓存层 :使用共享内存对象(SHM) 存储最近访问的主数据
- 按工厂 + 物料号建立复合键
-
存储序列化后的完整主数据集
-
逻辑层:实现增量更新机制
- 记录主数据最后修改时间戳
-
仅当源数据变更时才刷新缓存
-
容错层:数据库回退保障
- 缓存失效时自动切换标准逻辑
- 异常日志记录
代码实现
BAdI 实现类骨架
CLASS zcl_pp_order_update_badi IMPLEMENTATION.
METHOD if_ex_pporder_update~change_at_save.
" 1. 构建缓存键
DATA(lv_cache_key) = |{is_order-werk}{is_order-matnr}|.
" 2. 尝试从缓存获取
TRY.
DATA(lo_cache) = zcl_pp_cache_factory=>get_instance( ).
IF lo_cache->exists(lv_cache_key).
" 缓存命中逻辑
es_order_data = lo_cache->read(lv_cache_key).
RETURN.
ENDIF.
CATCH zcx_pp_cache_error INTO DATA(lx_error).
" 记录错误并继续执行标准逻辑
zcl_pp_logger=>log_error(lx_error).
ENDTRY.
" 3. 标准逻辑回退
super->change_at_save(
EXPORTING
is_order = is_order
iv_upd_flag = iv_upd_flag
IMPORTING
es_order_data = es_order_data ).
" 4. 更新缓存
IF lo_cache IS BOUND.
lo_cache->update(
iv_key = lv_cache_key
iv_data = es_order_data
iv_expiry = 3600 ). " 1 小时 TTL
ENDIF.
ENDMETHOD.
ENDCLASS.
缓存失效策略
METHOD refresh_on_master_change.
" 监听主数据变更事件
GET TIME STAMP FIELD DATA(lv_timestamp).
" 比较时间戳差异
SELECT SINGLE last_change
FROM marc
INTO @DATA(lv_db_timestamp)
WHERE werks = @iv_plant
AND matnr = @iv_material.
IF lv_db_timestamp > iv_cached_timestamp.
" 触发缓存清理
zcl_pp_cache_factory=>get_instance()->invalidate( iv_key).
ENDIF.
ENDMETHOD.
生产考量
多客户端同步
- 采用跨客户端的共享内存区域
- 通过 SAP 锁对象协调写操作
- 定期清理无效缓存(SMON 事务配置)
性能数据对比
| 场景 | 平均响应时间(ms) | 数据库调用次数 |
|---|---|---|
| 标准逻辑 | 1200 | 15 |
| 增强方案(冷启动) | 1500 | 16 |
| 增强方案(缓存命中) | 350 | 2 |
事务一致性
- 在 COMMIT WORK 阶段更新缓存
- 使用 SAVE ROLLBACK AREA 保障原子性
- 实现 BAdI 的晚触发点(LATE 模式)
避坑指南
- 缓存雪崩预防
- 设置分级 TTL(基础数据 1 小时,业务数据 10 分钟)
-
添加随机抖动因子:
iv_expiry = 3600 + rand(600) -
调试技巧
" 在 SAT 跟踪中过滤增强调用 SET RUN TIME ANALYZER ON. FILTER: PROGRAM = 'ZCL_PP_ORDER_UPDATE*'. -
传输注意事项
- 共享内存对象需单独传输配置
- 生产系统需先在测试客户端验证
- 使用 SCU3 检查标准对象修改
扩展思考
当前方案在单系统内运行良好,但面对以下跨系统场景仍需改进:
- 如何同步不同 SAP 系统的缓存状态?
- 在 S /4HANA 与 ECC 混合环境中如何保持兼容?
- 是否适合采用 CPI 作为中央缓存协调器?
欢迎在评论区分享你的分布式方案设计思路。
正文完
