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 默认使用 REPEATABLE READ 隔离级别,其实现语义接近快照隔离;在悲观事务模式下也支持 READ COMMITTED。TiDB 使用 Raft 保证 TiKV 多副本之间的数据一致性,跨节点事务则主要通过 Percolator 事务模型和两阶段提交协议实现。TiDB 与 SQL Server、MySQL 的锁和隔离行为均存在差异,迁移前需要针对并发更新、锁等待、死锁和事务重试进行专项验证。
如果你正在规划 SQL Server 迁移,建议先梳理当前的事务配置和锁依赖逻辑,再在目标数据库上做一轮并发场景的 POC 验证。