最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SQL存储过程中重试机制的实现策略是什么
时间:2026-07-15 19:59:52 编辑:袖梨 来源:一聚教程网
SQL Server 存储过程中无法用TRY CATCH捕获1205死锁错误,因其会直接终止执行上下文;重试必须由最外层批处理包裹整个事务(BEGIN TRAN/EXEC/COMMIT),并显式判断ERROR_NUMBER()=1205,配合WAITFOR DELAY延时且限重试次数。
SQL Server 存储过程里不能用 TRY CATCH 捕获 1205 死锁错误
死锁发生时,SQL Server 会直接终止当前执行上下文,BEGIN TRY 块根本不会进入 CATCH。你在存储过程里写再多层嵌套,只要错误号是 1205,控制权就不会跳进去。常见错误现象包括:应用层仍收到 Transaction (Process ID XX) was deadlocked;CATCH 里的 WAITFOR DELAY 完全没执行;在触发器或嵌套过程中放重试逻辑也无效。
重试必须由最外层批处理控制,且包裹整个事务
真正能捕获并重试的位置,是调用该存储过程的那个 T-SQL 批处理(比如 SSMS 查询窗口、SQLCMD 脚本、或应用拼接后发送的完整语句块)。关键点不是“在哪写重试”,而是“重试什么”:
- 必须把
BEGIN TRANSACTION、EXEC YourStoredProcedure、COMMIT TRANSACTION全部包进TRY块内 - 单独对某条
UPDATE加 TRY CATCH 并重试,会导致@@TRANCOUNT错乱、事务状态污染 -
ERROR_NUMBER()必须显式判断是否等于1205,其他错误(如约束冲突、超时)不应重试 -
WAITFOR DELAY '00:00:00.05'是底线,太短易引发重试风暴;超过 3 次必须THROW原错误
MySQL 存储过程可用 DECLARE EXIT HANDLER 实现有限重试
MySQL 支持在存储过程中用 DECLARE EXIT HANDLER FOR 1213, 1205 捕获死锁和锁超时,但有硬性限制:
- 外部不能已开启事务,否则
START TRANSACTION会报错ERROR 1305 (42000): SAVEPOINT does not exist - 必须显式
ROLLBACK后再调用DO SLEEP(0.01),不能用WAITFOR(那是 SQL Server 语法) - 重试逻辑要包裹整个事务块,而非单条语句;示例中用
@retry := @retry + 1计数,IF @retry 控制上限
Oracle 存储过程靠 SAVEPOINT + LOOP 实现可控重试
Oracle 没有 TRY CATCH,但可用 SAVEPOINT 配合 EXCEPTION WHEN OTHERS 回退到干净状态:
- 每次循环开始前设
SAVEPOINT sp_start,失败后ROLLBACK TO sp_start,避免状态累积 - 禁止在循环内
COMMIT;所有COMMIT必须放在成功退出循环之后 - 优先捕获具体异常码(如
ORA-03113、ORA-03114),而非只写WHEN OTHERS -
DBMS_SCHEDULER.CREATE_JOB的max_failures不是过程内重试——那是任务级调度,每次都是全新会话,和事务重试无关
相关文章
- 王者荣耀世界零氪玩家如何生存 07-28
- 快手极速版怎么绑定手机号 07-28
- 明日方舟和轻松小熊联动活动内容一览 07-28
- 逆战未来黎明之光 逆战未来黎明之光玩法机制与新手入门指南 07-28
- 植物大战僵尸融合版毁灭土豆地雷介绍 07-28
- 逆战未来飓风之龙 逆战未来飓风之龙武器获取方法详解 07-28