LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL Server事务处理详解:从入门到精通

admin
2026年4月15日 15:1 本文热度 46

今天我们来深入探讨SQL Server中非常重要的话题——事务处理。掌握事务处理,让你的数据操作更加安全可靠!

一、什么是事务?

事务是单个的工作单元。如果某一事务成功,则在该事务中进行的所有数据更改均会提交,成为数据库中的永久组成部分。如果事务遇到错误且必须取消或回滚,则所有数据更改均被清除。

简单理解:事务就像银行转账,要么同时成功(扣款+存款),要么同时失败,不会出现扣了钱但没到账的情况。

二、事务的三种运行模式

1. 自动提交事务

每条单独的语句都是一个事务。这是SQL Server的默认模式。

-- 每条语句自动提交INSERT INTO users VALUES ('张三'25)UPDATE users SET age = 26 WHERE name = '张三'

2. 显式事务

每个事务均以BEGIN TRANSACTION显式开始,以COMMIT或ROLLBACK显式结束。

BEGIN TRANSACTION    UPDATE account SET balance = balance - 100 WHERE id = 1    UPDATE account SET balance = balance + 100 WHERE id = 2COMMIT TRANSACTION

3. 隐性事务

在前一个事务完成时,新事务隐式启动,但每个事务仍以COMMIT或ROLLBACK显式完成

-- 开启隐性事务模式SET IMPLICIT_TRANSACTIONS ON
-- 以下操作会自动开始新事务INSERT INTO users VALUES ('李四'30)UPDATE users SET age = 31 WHERE name = '李四'COMMIT TRANSACTION  -- 显式提交
-- 下一个操作又会自动开始新事务DELETE FROM users WHERE name = '李四'ROLLBACK TRANSACTION  -- 显式回滚

三、事务操作核心语法

1. BEGIN TRANSACTION - 开始事务

标记一个显式本地事务的起始点,将@@TRANCOUNT加1。

-- 基本语法BEGIN TRAN [SACTION] [transaction_name | @tran_name_variable]
-- 示例:嵌套事务BEGIN TRAN T1    UPDATE table1 SET col1 = 'value1'
    -- 嵌套事务M2    BEGIN TRAN M2 WITH MARK '标记说明'        UPDATE table2 SET col2 = 'value2'        SELECT * FROM table1    COMMIT TRAN M2
    UPDATE table3 SET col3 = 'value3'COMMIT TRAN T1

2. BEGIN DISTRIBUTED TRANSACTION - 分布式事务

指定由MS DTC管理的分布式事务的起始。

-- 示例:跨服务器更新BEGIN DISTRIBUTED TRANSACTION    UPDATE authors SET au_lname = 'McDonald'     WHERE au_id = '409-56-7008'
    -- 调用远程服务器存储过程    EXECUTE link_Server_T.pubs.dbo.changeauth_lname         '409-56-7008''McDonald'COMMIT TRAN
注意:需要安装MS DTC,且链接服务器的RPC选项必须设为True。

3. SET XACT_ABORT - 错误处理设置

指定当产生运行时错误时,是否自动回滚当前事务

-- 设置为OFF(默认):只回滚出错语句SET XACT_ABORT OFFBEGIN TRAN    INSERT INTO t2 VALUES (1)  -- 成功    INSERT INTO t2 VALUES (2)  -- 外键错误,只回滚本条    INSERT INTO t2 VALUES (3)  -- 成功执行COMMIT TRAN  -- 事务提交,1和3被保存
-- 设置为ON:任何错误都回滚整个事务SET XACT_ABORT ONBEGIN TRAN    INSERT INTO t2 VALUES (4)  -- 成功    INSERT INTO t2 VALUES (5)  -- 外键错误,整个事务回滚    INSERT INTO t2 VALUES (6)  -- 不会执行COMMIT TRAN  -- 所有修改都被撤销

4. SAVE TRANSACTION - 设置保存点

在事务内设置保存点,可以有条件地取消事务的一部分。

BEGIN TRANSACTION    -- 设置保存点A    SAVE TRANSACTION A
    INSERT INTO demo VALUES('BB''B term')
    -- 回滚到保存点A(只撤销上面的插入)    ROLLBACK TRANSACTION A
    -- 创建新表(不受回滚影响)    CREATE TABLE demo2 (name varchar(10), age int)    INSERT INTO demo2 VALUES('lis'1)
COMMIT TRANSACTION  -- 提交创建表和插入操作

5. ROLLBACK TRANSACTION - 回滚事务

将事务回滚到起点或某个保存点。

-- 回滚整个事务BEGIN TRANSACTION    INSERT INTO users VALUES ('王五'28)    UPDATE users SET age = 29 WHERE name = '王五'ROLLBACK TRANSACTION  -- 所有修改都被撤销
-- 回滚到保存点BEGIN TRANSACTION    INSERT INTO users VALUES ('赵六'22)    SAVE TRANSATION SavePoint1    INSERT INTO users VALUES ('钱七'24)    ROLLBACK TRANSACTION SavePoint1  -- 只回滚钱七的插入COMMIT TRANSACTION  -- 赵六被提交

6. COMMIT TRANSACTION - 提交事务

标志一个成功的事务结束,使修改成为数据库的永久部分。

BEGIN TRANSACTION A    INSERT INTO demo VALUES('BB''B term')COMMIT TRANSACTION A  -- 提交事务

四、嵌套事务处理

SQL Server中的嵌套事务将内部事务合并到外部事务中

-- 示例1:嵌套事务回滚BEGIN TRAN t1    INSERT INTO demo2 VALUES('lis'1)
    BEGIN TRAN t2        INSERT INTO demo VALUES('BB''B term')    ROLLBACK TRAN t2  -- 错误!不能回滚内部事务名
    INSERT INTO demo2 VALUES('lis'2)COMMIT TRAN t1
-- 示例2:正确的嵌套事务BEGIN TRAN t1    INSERT INTO demo2 VALUES('lis'1)
    BEGIN TRAN t2        INSERT INTO demo VALUES('BB''B term')    COMMIT TRAN t2  -- 内部事务提交
    INSERT INTO demo2 VALUES('lis'2)COMMIT TRAN t1  -- 外部事务提交,所有操作生效

五、事务隔离级别

设置锁超时

-- 设置锁超时时间为5000毫秒SET LOCK_TIMEOUT 5000
-- 设置为0,立即解锁(不等待)SET LOCK_TIMEOUT 0
-- 设置为-1(默认),无限等待SET LOCK_TIMEOUT -1

五种隔离级别

-- 1. READ UNCOMMITTED(脏读)SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED-- 可以读取未提交的数据,性能最好,但数据可能不一致
-- 2. READ COMMITTED(默认,避免脏读)SET TRANSACTION ISOLATION LEVEL READ COMMITTED-- 只能读取已提交的数据,但不能保证可重复读
-- 3. REPEATABLE READ(可重复读)SET TRANSACTION ISOLATION LEVEL REPEATABLE READ-- 防止其他事务更新已读取的数据,但可能产生幻像行
-- 4. SERIALIZABLE(可序列化)SET TRANSACTION ISOLATION LEVEL SERIALIZABLE-- 最严格的级别,防止其他事务插入、更新、删除-- 相当于在所有SELECT语句上设置HOLDLOCK
-- 5. SNAPSHOT(快照隔离)SET TRANSACTION ISOLATION LEVEL SNAPSHOT-- 使用行版本控制,读取操作不会阻塞写入操作

六、实际应用场景

场景1:银行转账(原子性保证)

BEGIN TRY    BEGIN TRANSACTION
        -- 检查余额        DECLARE @balance DECIMAL(10,2)        SELECT @balance = balance FROM accounts         WHERE account_id = 1001 AND account_status = 'ACTIVE'
        IF @balance < 1000            THROW 50000'余额不足'1
        -- 扣款        UPDATE accounts         SET balance = balance - 1000         WHERE account_id = 1001
        -- 存款        UPDATE accounts         SET balance = balance + 1000         WHERE account_id = 1002
        -- 记录交易日志        INSERT INTO transaction_log (from_account, to_account, amount, trans_time)        VALUES (100110021000, GETDATE())
    COMMIT TRANSACTION    PRINT '转账成功'END TRYBEGIN CATCH    ROLLBACK TRANSACTION    PRINT '转账失败:' + ERROR_MESSAGE()END CATCH

场景2:订单处理(一致性保证)

BEGIN TRANSACTION    -- 设置保存点    SAVE TRANSACTION OrderCreate
    -- 创建订单    INSERT INTO orders (order_no, customer_id, order_date, total_amount)    VALUES ('ORD2024001'101, GETDATE(), 299.00)
    DECLARE @order_id INT = SCOPE_IDENTITY()
    -- 添加订单明细    INSERT INTO order_details (order_id, product_id, quantity, price)    VALUES (@order_id1001299.50)
    -- 检查库存    IF NOT EXISTS (        SELECT 1 FROM inventory         WHERE product_id = 1001 AND quantity >= 2    )    BEGIN        ROLLBACK TRANSACTION OrderCreate        PRINT '库存不足,订单创建失败'        RETURN    END
    -- 扣减库存    UPDATE inventory     SET quantity = quantity - 2     WHERE product_id = 1001
COMMIT TRANSACTIONPRINT '订单创建成功'

场景3:分布式事务(跨数据库操作

-- 前提:配置链接服务器和MS DTCBEGIN DISTRIBUTED TRANSACTION
    -- 本地数据库操作    UPDATE LocalDB.dbo.Products     SET Stock = Stock - 5     WHERE ProductID = 101
    -- 远程数据库操作    EXEC RemoteDB.warehouse.dbo.sp_UpdateStock         @ProductID = 101        @Quantity = -5
COMMIT TRANSACTION

七、事务最佳实践

1. 事务设计原则

  • 保持简短:事务越短,锁定资源的时间越少

  • 避免用户交互:不要在事务中等待用户输入

  • 合理使用隔离级别:根据业务需求选择适当级别

2. 错误处理模板

SET XACT_ABORT ON  -- 推荐在存储过程中开启SET NOCOUNT ON
BEGIN TRY    BEGIN TRANSACTION
        -- 业务逻辑代码
    COMMIT TRANSACTIONEND TRYBEGIN CATCH    IF @@TRANCOUNT > 0        ROLLBACK TRANSACTION
    -- 记录错误日志    INSERT INTO ErrorLog (ErrorMessage, ErrorSeverity, ErrorTime)    VALUES (ERROR_MESSAGE(), ERROR_SEVERITY(), GETDATE())
    THROW  -- 重新抛出错误END CATCH

3. 死锁预防

  • 按相同顺序访问资源

  • 使用较低的隔离级别

  • 考虑使用行版本控制隔离级别

  • 设置合理的锁超时时间

八、常见问题解答

Q1:事务嵌套时,@@TRANCOUNT的值如何变化?
A:每进入一个BEGIN TRANSACTION,@@TRANCOUNT增加1;每执行一个COMMIT,减少1;ROLLBACK会将@@TRANCOUNT置为0。

Q2:如何在事务中查看当前事务层数?
A:使用SELECT @@TRANCOUNT查看当前嵌套层级。

Q3:保存点有什么限制?
A:分布式事务中不支持保存点;回滚到保存点不会释放锁。

总结

事务是保证数据一致性的重要机制,合理使用事务能够:

  • ✅ 保证数据的原子性(Atomicity)

  • ✅ 维护数据的一致性(Consistency)

  • ✅ 实现操作的隔离性(Isolation)

  • ✅ 确保修改的持久性(Durability)

掌握事务处理,让你的数据库操作更加专业可靠!


阅读原文:原文链接


该文章在 2026/4/15 18:15:32 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-9  粤公网安备44030602007207号