如何在TypeORM迁移中创建SQL Server全文目录?解决事务报错
解决TypeORM迁移中创建SQL Server全文目录的事务问题
在Node.js、Nest.js、TypeORM搭配Microsoft SQL Server的环境下配置全文搜索时,执行创建全文目录的迁移会报错——SQL Server不允许在用户事务内执行CREATE FULLTEXT CATALOG语句,但TypeORM的QueryRunner默认会为迁移启动事务。
迁移代码及报错信息
迁移代码
import { MigrationInterface, QueryRunner } from 'typeorm'; export default class addFullTextIndexToAttachmentComments1663750544577 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { await queryRunner.query(`--sql CREATE FULLTEXT CATALOG AttachmentComment `); } public async down(queryRunner: QueryRunner): Promise<void> { await queryRunner.query(`--sql DROP FULLTEXT CATALOG AttachmentComment `); } }
报错信息
QueryFailedError: Error: CREATE FULLTEXT CATALOG statement cannot be used inside a user transaction.
解决方案
方法:禁用当前迁移的事务
TypeORM允许为单个迁移类设置transaction = false,让该迁移执行时不启动事务,刚好适配SQL Server创建全文目录的要求。修改后的迁移代码如下:
import { MigrationInterface, QueryRunner } from 'typeorm'; export default class addFullTextIndexToAttachmentComments1663750544577 implements MigrationInterface { // 禁用该迁移的事务支持 transaction = false; public async up(queryRunner: QueryRunner): Promise<void> { // 添加存在性检查,避免重复创建报错 await queryRunner.query(` IF NOT EXISTS (SELECT * FROM sys.fulltext_catalogs WHERE name = 'AttachmentComment') CREATE FULLTEXT CATALOG AttachmentComment `); } public async down(queryRunner: QueryRunner): Promise<void> { // 添加存在性检查,避免删除不存在的目录报错 await queryRunner.query(` IF EXISTS (SELECT * FROM sys.fulltext_catalogs WHERE name = 'AttachmentComment') DROP FULLTEXT CATALOG AttachmentComment `); } }
注意事项
- 禁用事务后,该迁移的操作无法自动回滚,因此建议添加SQL语句的存在性检查,确保操作幂等,避免重复执行时出错。
- 仅在确实不需要事务的迁移中使用该设置,涉及数据修改的迁移仍建议保留事务支持。
内容的提问来源于stack exchange,提问作者Serhii Pemakhov
相关产品推荐
相关产品推荐

