#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 => {..});
Спасибо