SQL Server 的事务模型有自己的特点:默认 READ COMMITTED 隔离级别、基于锁的并发控制、可选的 RCSI(READ COMMITTED SNAPSHOT)和乐观并发控制。迁移到其他数据库后,事务行为可能发生变化,如果不提前识别和适配,上线后可能出现数据不一致或死锁增多的问题。
事务隔离级别的差异
SQL Server 支持四种标准隔离级别加上两个快照隔离级别:
其中 RCSI 是 SQL Server 2005 引入的,启用后 READ COMMITTED 级别使用行版本控制而不是锁来保证一致性。很多 SQL Server 部署都启用了 RCSI,因为它显著减少了读写阻塞。
迁移到 MySQL 协议兼容的数据库
MySQL 的默认隔离级别是 REPEATABLE READ,比 SQL Server 的默认 READ COMMITTED 更严格。但实现方式不同:
迁移到其他数据库
Oracle 默认 READ COMMITTED,PostgreSQL 默认 READ COMMITTED。大部分数据库都支持标准的四种隔离级别,但具体行为(特别是 RR 级别下是否防止幻读)有差异。
锁行为的差异
这是 SQL Server 迁移中最容易出问题的地方。
锁升级
SQL Server 有锁升级机制:当单条语句在单个对象上获取的锁超过一定数量(默认 5000)时,SQL Server 会把行级锁或页级锁升级为表级锁。这个行为在其他数据库中不存在。
如果业务依赖锁升级不会发生(比如大量单行更新),迁移到其他数据库后行为基本一致。但如果业务中有大批量更新操作且依赖 SQL Server 的锁升级行为来保证串行化,就需要重新评估。
锁超时
SQL Server 可以设置 LOCK_TIMEOUT,超过指定时间等待锁就报错。其他数据库的锁等待超时机制不同:
死锁处理
SQL Server 的死锁检测会自动选择一个「牺牲者」回滚,并在错误日志中记录死锁图。迁移后需要确认目标数据库的死锁检测机制和错误信息格式,应用层的死锁重试逻辑可能需要适配。
乐观并发控制
SQL Server 支持乐观并发控制,可以在表级别启用 ROWVERSION(原 timestamp),通过版本号来检测并发修改冲突。迁移后如果目标数据库不支持类似的行版本机制,需要改为应用层实现乐观锁(如版本号字段 + CAS 更新)。
实际建议
第一,梳理当前的事务配置。 确认 SQL Server 是否启用了 RCSI、哪些表启用了乐观并发控制、是否有显式设置隔离级别的代码。
第二,识别依赖锁行为的业务逻辑。 特别是依赖锁升级、锁超时、死锁重试的逻辑,这些在迁移后行为可能不同。
第三,在目标数据库上做并发测试。 模拟业务的并发场景,观察锁等待、死锁、超时等行为是否符合预期。
TiDB 在 SQL Server 事务迁移中的对应能力
TiDB 兼容 MySQL 协议,默认隔离级别为 RC(可配置为 RR),基于 Multi-Raft 实现分布式事务,锁行为和 MySQL InnoDB 接近但不完全相同。TiDB 的 RR 不使用间隙锁,如果 SQL Server 业务依赖间隙锁来防止幻读,需要在应用层或设计层面做调整。建议在 POC 阶段用业务的典型并发场景做一轮压测,重点观察隔离级别和锁行为是否符合预期。
如果你正在规划 SQL Server 迁移,建议先梳理当前的事务配置和锁依赖逻辑,再在目标数据库上做一轮并发场景的 POC 验证。