You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:15:43