I'm trying to wrap our queries in transactions. The queries run fine without the transaction, however when I add the transaction it says it executes but nothing gets added to the Db.
import { Sequelize } from 'sequelize';
import SomeModel from '../database/models/some-model/';
...
@Inject('SEQUELIZE')
private readonly sequelizeInstance: Sequelize,
...
importSomething = {
try {
const somethings = await this.someService.getSomething();
if (Array.isArray(somethings)) {
const t = await SomeModel.sequelize.transaction();
const transactionHost = { transaction: t };
await SomeModel.bulkCreate(somethings, {
ignoreDuplicates: true,
...transactionHost
}).then(() => logger.info('some data has been saved'));
} else {
const message = 'No data available.';
logger.info(message);
return message;
}
} catch (e) {
const message = 'Error trying to import somethings.';
return LogExceptionResponse(
this.SERVICE_NAME,
GetCallerMethod(),
message,
e
);
}
}
on the console I get the following:
Executing (a7a21664-1c33-46ba-863d-376cd8d4daca): INSERT IGNORE INTO `some_log`
<things to insert>},
{
plain: false,
raw: false,
logging: [Function: log] { prototype: {} },
showWarnings: false,
validate: false,
hooks: true,
individualHooks: false,
ignoreDuplicates: true,
transaction: Transaction {
sequelize: Sequelize {
options: [Object],
config: [Object],
dialect: [MysqlDialect],
queryInterface: [MySQLQueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
repositoryMode: false
},
savepoints: [],
_afterCommitHooks: [],
options: { type: 'DEFERRED', isolationLevel: null, readOnly: false },
parent: undefined,
name: undefined,
id: 'a7a21664-1c33-46ba-863d-376cd8d4daca',
connection: Connection {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
config: [ConnectionConfig],
stream: [Socket],
_internalId: 3,
_commands: [Denque],
_command: undefined,
_paused: false,
_paused_packets: [Denque],
_statements: [LRUCache],
serverCapabilityFlags: 3489660927,
authorized: true,
sequenceId: 2,
compressedSequenceId: 0,
threadId: 227770646,
_handshakePacket: [Handshake],
_fatalError: null,
_protocolError: null,
_outOfOrderPackets: [],
clientEncoding: 'utf8',
packetParser: [PacketParser],
serverEncoding: 'utf8',
connectTimeout: null,
connectionId: 227770646,
_authPlugin: [Function (anonymous)],
uuid: 'a7a21664-1c33-46ba-863d-376cd8d4daca',
[Symbol(kCapture)]: false
}
},
model: SomeModel,
returning: true,
fields: [ 'id', 'someId', 'reason', 'createdAt' ],
type: 'INSERT'
}
23-03-07 14:50:06 INFO: some data has been saved
I've also tried
await this.sequelizeInstance.transaction(async (t) => {
const transactionHost = { transaction: t };
...
but I get sequelize is not a function as an error.
and
const t = Sequelize.transaction()
throws a transaction does not exist on type of Sequelize.
the database setup looks like this
import { ConfigService } from '@nestjs/config';
import { Sequelize } from 'sequelize-typescript';
import { Dialect } from 'sequelize/types';
import models from './models/index';
import winston from 'winston';
export const databaseProviders = [
{
provide: 'SEQUELIZE',
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
const dialect = configService.get('DATABASE_DIALECT');
const host = configService.get('DATABASE_HOST');
const username = configService.get('DATABASE_USER');
const password = configService.get('DATABASE_PASSWORD');
const database = configService.get('DATABASE');
const sequelize = new Sequelize({
dialect: dialect as Dialect,
host: host,
username: username,
password: password,
database: database,
logging: winston.error,
pool: {
max: 50,
min: 0,
acquire: 60000,
idle: 10000
}
});
sequelize.addModels(models);
await sequelize.sync();
return sequelize;
}
}
];
Thanks in advance.
In case of creating an unmanaged transaction you need to explicitly commit/rollback it:
const t = await SomeModel.sequelize.transaction();
try {
const transactionHost = { transaction: t };
await SomeModel.bulkCreate(somethings, {
ignoreDuplicates: true,
...transactionHost
})
await t.commit();
catch (err) {
await t.rollback();
}
In case of a managed transaction just check you call transaction
on Sequelize instance:
await this.sequelizeInstance.transaction(async (transaction) => {
await SomeModel.bulkCreate(somethings, {
ignoreDuplicates: true,
{
transaction
}
})
});