Как сообщить sequelize, какую базу данных использовать при создании транзакции?

#node.js #transactions #sequelize.js #nestjs

#node.js #транзакции #sequelize.js #nestjs

Вопрос:

Я работаю над API с использованием NestJS вместе с Sequelize. Я схожу с ума, пытаясь выполнить несколько запросов к базе данных с использованием транзакций. Проблема в том, что упомянутая база данных является второй, которую я определил для Sequelize в модуле моего приложения, и КАЖДАЯ транзакция, которую я создаю с помощью Sequelize, всегда использует первое соединение с базой данных, которая используется по умолчанию.

Вот мой файл app.module.ts:

 @Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'postgres',
      host: connection_1_dbserver,
      port: connection_1_port,
      username: connection_1_username,
      password: connection_1_pass,
      database: connection_1_dbname,
      models: [...],
      synchronize: false,
    }),
    SequelizeModule.forRoot({
      dialect: 'postgres',
      name: connection_2_NAME,
      host: connection_2_dbserver,
      port: connection_2_port,
      username: connection_2_username,
      password: connection_2_pass,
      database: connection_2_dbname,
      models: [...],
      synchronize: false,
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  

Я попытался создать транзакцию, используя прямое подключение ко второй базе данных (connection_2_NAME), и именно поэтому я ввожу ее в сервис. Итак, сервис выглядит следующим образом:

 @Injectable()
export class ExportService {
  constructor(
    @InjectConnection(connection_2_NAME)
    private readonly connection_2_name_ref,
    private sequelize: Sequelize,
  ) {}

public async export(id: number): Promise<{ code: number }> {
    let result = { code: 1 };
    ...
            try {
              return this.connection_2_NAME.transaction(transaction => {
                // First query
                return this.removeCurrData(
                  id,
                  transaction,
                )
                  .then(() => {
                    // Second query
                    return this.insertNewData(newData, id, transaction);
                  })
                  .then(exportResult => {
                    if (exportResult) {
                      result.code = 3;
                    } else result.code = 2;
                    return resu<
                  });
              });
            } catch (error) {
              result.code = 2;
              return resu<
            }
          } else result.code = 2;
    ...
    }
    return resu<
  }
  

Connection_2_NAME.transaction() выдает мне транзакцию, но она фиксируется после успешного выполнения первого запроса в цепочке. Как запросить второе соединение sequelize DB в конфигурации с использованием транзакций?

Заранее благодарю вас за помощь!

РЕШЕНИЕ:

Я должен был внедрить экземпляр Sequelize для данного соединения. Но вместо этого я создавал новую ссылку на это соединение, чтобы использовать ее позже при создании транзакции. По этой причине введенный экземпляр Sequelize был связан с подключением по умолчанию, а не с тем, которое мне нужно было использовать. Итак, всегда убедитесь, что у вас есть правильная инъекция экземпляра…

 constructor(
    @InjectConnection(connection_2_NAME)
    private sequelize: Sequelize,
  ) {}
  

После этого вы можете работать с транзакцией как обычно:

 return this.sequelize.transaction(async t => {...}); // t is the transaction to execute queries using models managed by the connection_2_NAME connection.
  

Я все еще учусь, но надеюсь, что это кому-то поможет. Счастливого кодирования 😉

Комментарии:

1. Это было бы проще для чтения async/await . Можете ли вы включить код для removeCurrData() и insertNewData() ?

2. Мой плохой! @doublesharp Я уже понял, в чем была моя ошибка. Проблема в том, что когда я вводил соединение, по какой-то причине вместо того, чтобы вводить экземпляр Sequelize для данного соединения, я создавал новую ссылку на него. Правильный способ: constructor( @InjectConnection(connection_2_NAME) private sequelize: Sequelize, ) {} Затем создал транзакцию как обычно: return this.sequelize.transaction(async transaction => {..}); Спасибо