当前位置: 首页 > ds >正文

SQL Server 存储过程开发手册

SQL Server 存储过程开发手册(更新版)

根据要求,重新整理并加入了事务控制、异常日志记录和返回状态码的设计。以下是详细说明:


1. 总则

1.1 目标

本手册旨在为 SQL Server 存储过程的编写提供一套完整的规范,确保系统的事务控制、异常处理、日志记录和状态码返回清晰明确,优化数据一致性、系统稳定性和性能。


2. 事务控制与层次化设计

2.1 事务控制原则

根据业务的需求和事务的粒度,存储过程应分为不同的层次,每个层次的事务控制和异常处理策略不同,具体如下表所示:

层次控制事务记录异常日志返回状态码
主流程 (Main)
子事务 (SubTx)
功能性操作 (Func)可选
  • 主流程 (Main)

    • 不控制事务,负责协调和调用子事务或功能性操作。

    • 记录异常日志,捕获并输出错误信息。

    • 返回状态码,以通知调用方执行状态(成功或失败)。

  • 子事务 (SubTx)

    • 控制事务,开始和提交或回滚事务。

    • 记录异常日志,在发生异常时捕获并输出错误信息。

    • 返回状态码,标识事务是否成功完成。

  • 功能性操作 (Func)

    • 不控制事务,通常是读取操作或不涉及数据修改的辅助功能。

    • 不记录异常日志(除非必要),通常这些操作在主流程中捕获异常。

    • 返回状态码可选,根据具体业务需要决定是否返回。


3. 存储过程命名规范

存储过程命名应该遵循以下结构,便于识别和维护:

proc_领域_子领域_类型
  • 领域 (Domain):表示存储过程所属的业务领域,如订单、用户、商品等。

  • 子领域 (SubDomain):表示存储过程在领域中的具体细分模块,如发货、支付、库存等。

  • 类型 (Type):表示存储过程的类型,分为三种类型:

    • Main:主流程,负责协调其他子事务和功能性操作。

    • SubTx:子事务,负责数据更新和事务控制。

    • Func:功能性操作,通常是查询或计算操作。

3.1 示例命名

  • proc_Order_Shipment_SubTx:表示“订单”领域中的“发货”子领域的子事务,涉及事务控制。

  • proc_Order_Payment_Main:表示“订单”领域中的“支付”子领域的主流程,负责调用其他子事务。

  • proc_Inventory_Check_Func:表示“库存”领域中的“检查”功能,通常用于查询操作,不涉及事务控制。


4. 存储过程设计与事务控制

4.1 主流程存储过程

主流程存储过程不涉及事务控制,它的职责是调用子事务和功能性操作,并记录异常日志和返回执行状态码。

CREATE PROCEDURE proc_Order_Shipment_Main@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGINBEGIN TRY-- 调用子事务,子事务控制事务EXEC proc_Order_Shipment_SubTx @OrderId, @code,@msg  ;if(@code!=200){-- 记录失败原因,处理失败带来的影响return}-- 调用功能性操作(如果需要)EXEC proc_Inventory_Check_Func @OrderId, @code,@msg ;if(@code!=200){-- 记录失败原因,处理失败带来的影响return}-- 返回成功状态码set @code=200END TRYBEGIN CATCH-- 捕获并记录异常日志PRINT 'Error in proc_Order_Shipment_Main: ' + ERROR_MESSAGE();-- 返回失败状态码RETURN 1; -- 状态码:1 表示失败END CATCH
END;

4.2 子事务存储过程

子事务存储过程负责控制事务,它需要开始、提交和回滚事务,并在发生异常时记录日志和返回状态码。

CREATE PROCEDURE proc_Order_Shipment_SubTx@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGIN-- 开始事务BEGIN TRANSACTION;BEGIN TRY-- 订单发货相关的数据库操作UPDATE dbo.OrderSET ShipmentStatus = 'Shipped'WHERE OrderId = @OrderId;-- 提交事务COMMIT TRANSACTION;-- 返回成功状态码RETURN 0; -- 状态码:0 表示成功END TRYBEGIN CATCH-- 发生错误时回滚事务ROLLBACK TRANSACTION;-- 记录异常日志PRINT 'Error in proc_Order_Shipment_SubTx: ' + ERROR_MESSAGE();-- 返回失败状态码RETURN 1; -- 状态码:1 表示失败END CATCH
END;

4.3 功能性操作存储过程

功能性操作通常是只执行查询或计算,不涉及数据修改,因此不控制事务。日志记录和状态码返回可选,具体业务需求决定。

CREATE PROCEDURE proc_Inventory_Check_Func@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGIN-- 查询操作,检查库存SELECT ProductId, AvailableStockFROM dbo.InventoryWHERE ProductId IN (SELECT ProductId FROM dbo.OrderItems WHERE OrderId = @OrderId);
END;

5. 错误处理与日志记录

5.1 错误处理

  • 主流程:主流程存储过程捕获所有子事务和功能性操作中的异常,但不控制事务回滚。它应当记录异常日志,并返回相应的状态码(通常是 0 或 1)。

  • 子事务:子事务存储过程必须通过 BEGIN TRYBEGIN CATCH 语句来捕获异常,并在异常发生时回滚事务。所有异常都应该记录日志,并返回状态码,标识事务是否成功。

  • 功能性操作:功能性操作通常不捕获异常,也不记录日志,异常处理依赖于主流程。

5.2 异常日志记录

所有的异常都应通过日志记录下来,方便后期排查和优化。可以使用 PRINTRAISEERROR 语句来记录错误消息。

BEGIN CATCHPRINT 'Error: ' + ERROR_MESSAGE();-- 或者使用 RAISEERROR 记录更详细的日志-- RAISEERROR('Error in procedure: %s', 16, 1, ERROR_MESSAGE());THROW;
END CATCH

6. 返回状态码

每个存储过程在执行完毕后应返回一个状态码,状态码通常为:

  • 0:表示操作成功。

  • 1:表示操作失败(可根据需要扩展更多状态码,表示不同类型的错误)。

返回状态码用于调用方判断存储过程执行是否成功,并做相应的处理。


7. 性能优化与锁争用

  • 避免长事务:事务内只包含必要的数据库操作,避免外部接口或延时任务的调用。

  • 批量处理:对于需要更新大量数据的操作,尽量使用批量处理,减少事务锁的持有时间。

  • 索引优化:确保数据库表有适当的索引,以加速查询和数据操作。


8. 审查与监控

8.1 代码审查标准

  • 确保每个存储过程的事务控制符合规范。

  • 确保异常处理机制完备,并且日志记录充分。

  • 确保存储过程有清晰的返回状态码,便于系统监控。

8.2 监控与日志

  • 监控长时间运行的事务,避免事务阻塞。

  • 配置合适的告警机制,及时捕获死锁或其他异常。


总结

  • 通过分层设计,每个存储过程的责任清晰,主流程不控制事务,子事务控制事务,功能性操作不涉及事务管理。

  • 存储过程命名规则统一,便于后续维护和扩展。

  • 错误处理和日志记录是保证系统稳定性的关键,每个存储过程都应有明确的异常处理和日志记录机制。

http://www.xdnf.cn/news/2699.html

相关文章:

  • 2025系统架构师---主程序/子程序架构风格
  • 小白学习java第16天(上): javaWeb
  • 【Redis】基础3:一些应用场景
  • TCP协议
  • 2个关键思路,让微课动画场景制作别具一格
  • Fps鬼泣总结:通信——伤害检测
  • 【数据结构】顺序表
  • 伺服电机AB相输出,接入定时器通道,对定时器IO口的速率有何要求【详细分析】
  • 【Unity完整游戏开发案例】从0做一个太空大战游戏
  • MySQL主从同步原理与实践 - Java架构师面试解析
  • 【Python】Matplotlib:立体永生花绘制
  • 单值映射、多值映射
  • Linux:进程间通信->共享内存
  • 开源网络入侵检测与防御系统:Snort
  • 企业私有大模型DeepSeek落地部署该用什么? Ollama还是vLLM
  • PlatformIO 入门学习笔记(一):背景了解
  • 【每天一个知识点】correntropy(相关熵)
  • 08-STM32外部中断
  • el-input限制输入只能是数字 限制input只能输入数字
  • 中国区域250米归一化植被指数数据集(2000-2023)
  • 迅雷精简绿色融合版【高速下载版】12.1.9.2870【11.2.2.1716】【20250426】
  • 树莓派学习专题<10>:使用V4L2驱动获取摄像头数据--申请和管理缓冲区
  • 【PVR】《Adaptive Palm Vein Recognition Method》
  • codeforcesB. Binary Colouring
  • 实人认证开发指南:用API+深度学习构建人证合一系统
  • 【CF】Day45——Codeforces Round 1021 (Div. 2) BC
  • UV工具的安装与使用
  • 2025系统架构师---数据抽象(Data Abstraction)‌与‌面向对象架构风格
  • Android原生开发基础
  • 龙芯远程方案