执行SQL存储过程后出现事务计数不匹配错误该如何解决?
问题根因与修复方案
1. 事务计数不匹配错误修复
你遇到的266错误是典型的事务操作逻辑错误,根因是当前存储过程中RETURN @InUse语句写在了COMMIT TRANSACTION之前:存储过程执行到RETURN时会直接终止执行,后续的COMMIT语句永远不会被触发,你开启的事务没有被提交,因此出现事务计数不匹配的报错。
你可以直接使用修正后的存储过程,同时调整逻辑符合业务预期:
CREATE PROCEDURE [dbo].[DeleteOption] @featureOptionId VARCHAR(256) AS BEGIN SET XACT_ABORT ON; SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; DECLARE @InUse tinyint = 5; -- 默认返回0表示删除成功 DECLARE @ReturnCode tinyint = 0; BEGIN TRANSACTION; -- 存在关联记录时返回占用状态 IF EXISTS (SELECT 1 FROM OptionsSet WHERE FeatureOptionID = @featureOptionId) BEGIN SET @ReturnCode = @InUse END ELSE BEGIN -- 无关联记录执行删除 DELETE FROM FeatureOptions WHERE FeatureOptionID = @featureOptionId END -- 确保事务先提交再返回 COMMIT TRANSACTION; RETURN @ReturnCode END GO
2. @featureOptionId类型验证
boost::uuids::uuid转换为标准字符串格式后长度为36位,你当前使用的VARCHAR(256)完全可以容纳,类型符合使用需求。如果想要优化性能,可以将参数类型改为UNIQUEIDENTIFIER,C++侧可直接传递uuid的二进制值,无需额外做字符串转换,也能避免格式匹配问题。
后续排查验证步骤
- 替换存储过程后,先在SQL Server Management Studio中手动传入测试参数执行,验证事务是否正常提交、返回值是否符合业务预期
- 检查C++代码中
boost::uuids::uuid转字符串的逻辑,确认输出格式和数据库中FeatureOptionID字段的存储格式完全一致,避免因大小写、短横线有无等问题导致条件匹配失败 - 若删除操作偶尔出现锁超时,可根据业务场景适当调整事务隔离级别,或增加索引优化查询速度
内容的提问来源于stack exchange,提问作者David Hovsepyan
相关产品推荐
相关产品推荐

