主题
单据异常锁定:审核不了、弃审不了、月结卡住
**脱敏声明。**本案例为真实项目复盘,按站内脱敏规范隐去客户名称、真实金额与业务截图。
一、背景
某离散制造客户,U8 V13.0,日常单据量中等(每天约 200 张出入库单)。某天上午,多个操作员同时反映:采购入库单审核报「单据已被锁定」,销售出库单弃审报「当前单据正在被其他操作员使用」。
重启客户端无效,问题持续一上午,业务积压。
二、需求
客户要的是立刻能干活,不是听你讲锁机制原理。审核、弃审、月结三条线都被卡住,属于「业务停摆级」故障。
三、诊断
排查路径
- 先确认是单张单据锁定还是表级锁:换一台机器试,多张单据试
- 查
UFSystem库的锁定表(UA_Log/UA_Task)——U8 的异常任务残留是头号嫌疑 - 查数据库当前阻塞:
sys.dm_exec_requests看 blocking_session_id - 回溯当天有没有异常退出:断电、杀进程、网络中断
定位结论
| 类型 | 特征 | 占比 |
|---|---|---|
| A | 客户端强杀进程(任务管理器结束),UA_Task 残留任务记录,单据锁没释放 | 约 8 成 |
| B | 网络闪断,客户端进程还在但连接已死,服务端认为任务未结束 | 约 2 成 |
根因:U8 的锁机制依赖 UA_Task 任务表。正常退出会清理任务记录,异常退出(强杀/断网)不清理,残留任务把单据锁死。这是 U8 全系的老毛病,不是数据坏了。
四、方案
- 短期(立刻救火) —— 清除
UA_Task残留任务(先备份,只删当前无活动连接的任务),锁定即释放 - 长期(防复发) —— 给客户端统一配置「超时自动清理」;教育用户不要用任务管理器强杀;出问题时先看锁定表而不是重启服务器
五、配置
清理残留任务 SQL(U8 专用)
sql
-- 用途:清理 UA_Task 残留任务,释放单据锁定
-- 方言:T-SQL (SQL Server),在 UFSystem 库执行
-- 参数:无(先查询,确认后再删)
-- 第一步:查看当前残留任务
SELECT cAcc_Id, cUser_Id, cTaskId, dStartTime, dSaveTime
FROM UA_Task
WHERE dSaveTime < DATEADD(HOUR, -2, GETDATE()); -- 2小时前的任务基本是残留
-- 第二步:确认这些任务没有活动连接后删除
-- DELETE FROM UA_Task
-- WHERE dSaveTime < DATEADD(HOUR, -2, GETDATE());⚠️ 危险操作提醒:删除前务必确认没有正在操作的用户。建议先执行第一步,人工核对任务对应的用户是否还在干活,再执行第二步。批量删除要在业务低峰做。
Oracle 写法差异:无对应机制(NC 的锁在
sm_lock等表,机制不同,详见排障手册)。
六、踩坑
- **别一上来就重启数据库。**重启能释放锁,但会把所有在线用户踢下线,制造新的抱怨。先清
UA_Task,不行再重启。 - **删 UA_Task 前必须核对。**有活动连接的任务删了,会导致那个用户操作异常。看
dSaveTime+ 跟用户确认双保险。 - **锁和「单据被他人使用」提示要区分。**前者是任务残留,后者可能是真的有人在操作同张单据,先沟通再动手。
- 服务器端的
UA_Task会自动清理部分过期任务,但不是所有场景都会清,强杀进程的残留一定要手工清。
七、验收
- 全部单据恢复审核/弃审,业务积压消化
- 连续 2 周无同类锁单投诉
- 客户操作员已了解「不要强杀客户端」的规范
八、回顾
做对的:先查锁定表定位到残留任务,5 分钟解决,没走「重启服务器」的笨路。
做得不够的:项目上线培训没讲「异常退出怎么办」,用户强杀进程成了习惯。下个项目把「异常退出的正确姿势」加进培训。
可复用:完整排查路径已沉淀进 排障手册-单据锁定,现场直接照着走。