nestjs - When using nested subscribers app will crash (NestJs+TypeOrm+Mysql)
问题描述
I have 1 controller, 3 services and 2 subscribers for service 1 and 2. when subscriber 2 will call create method of service 3, app will be stuck at loopback
flow:
I will call create method from service 1 at controller.
In subscriber 1 at afterInsert event, i will call create method of service 2.
Then in subscriber 2 at afterInsert event, i will call create method of service 3.
OrmConfig:
const config: MysqlConnectionOptions = {
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'secret',
database: 'db_name',
entities: ['dist/**/entities/*.entity{.ts,.js}'],
subscribers: ['dist/**/subscribers/*.subscriber{.ts,.js}'],
synchronize: false,
connectTimeout: 1500,
extra: {
connectionLimit: 20,
},
};
Controller:
@Contoller('order')
export class bankActionsControllerV1 {
constructor(private readonly bankActionsService: BankActionsService) {}
@Post('transfer')
async doTransferBankAction(@Body() body) {
return await this.bankActionsService.create({...body});
}
}
service 1:
@Injectable()
export class BankActionsService {
constructor(@InjectRepository(BankAction) private readonly bankActionsRepository: Repository<BankAction>) {}
public async create(data: CreateBankActionDto, additionalData?: ObjectLiteral): Promise<BankAction> {
const newBankAction = this.bankActionsRepository.create(data);
return await this.bankActionsRepository.save(newBankAction, { data: additionalData });
}
}
subscriber 1:
@Injectable()
export class BankActionsSubscriber implements EntitySubscriberInterface<BankAction> {
constructor(connection: Connection, @Inject(OrdersService) private readonly ordersService: OrdersService) {
connection.subscribers.push(this);
}
listenTo = () => BankAction;
async afterInsert(event: InsertEvent<BankAction>) {
return await this.ordersService.create(example_data); // <= service 2
}
}
service 2:
@Injectable()
export class OrdersService {
constructor(@InjectRepository(Order) private readonly ordersRepository: Repository<Order>) {}
public async create(data: CreateOrderDto): Promise<Order> {
const newOrder = this.ordersRepository.create(data);
return await this.ordersRepository.save(newOrder);
}
}
subscriber 2:
@Injectable()
export class OrdersSubscriber implements EntitySubscriberInterface<Order> {
constructor(connection: Connection, @Inject(TransactionsService) private readonly transactionsService: TransactionsService) {
connection.subscribers.push(this);
}
listenTo = () => Order;
async afterInsert(event: InsertEvent<Order>) {
return await this.transactionsService.create(example_data); // <= start crash
}
}
service 3:
@Injectable()
export class TransactionsService {
constructor(@InjectRepository(Transaction) private readonly transactionsRepository: Repository<Transaction>) {}
public async create(data: CreateTransactionDto): Promise<Transaction> {
const newTransaction = this.transactionsRepository.create(data);
return await this.transactionsRepository.save(newTransaction); // <= crash here
}
}
MySQL logs:
2021-11-16T13:28:41.099845Z 381 Connect root@172.18.0.1 on loyalty using TCP/IP
2021-11-16T13:28:41.144343Z 381 Query START TRANSACTION
2021-11-16T13:28:41.151288Z 381 Query INSERT INTO `bank_actions`(`id`, `author_id`, `merchant_id`, `customer_id`, `title`, `subtitle`, `description`, `type`, `uuid`, `extra`, `created_at`, `updated_at`) VALUES (DEFAULT, '3671', '45', '3671', DEFAULT, DEFAULT, DEFAULT, 'transfer', 'bc45980f-fef2-4b5a-b9be-cbb3d07600c5', '{\"amount\":1100,\"source\":\"7309877115803689\",\"destination\":\"8664825723794189\"}', '2021-11-16 16:58:41.000', '2021-11-16 16:58:41.000')
2021-11-16T13:28:41.160903Z 380 Query START TRANSACTION
2021-11-16T13:28:41.162365Z 380 Query INSERT INTO `orders`(`id`, `from_account_id`, `to_account_id`, `amount`, `UID`, `goods_id`, `goods_type`, `order_payment_id`, `settlement_id`, `campaign_id`, `author_id`, `merchant_id`, `campaign_calculate`, `from_treasury_account_id`, `to_treasury_account_id`, `paid_at`, `refund`, `cash_out`, `type`, `extra_values`, `credited_at`, `debited_at`, `created_at`, `updated_at`) VALUES (DEFAULT, '515723', '515722', 1100, '16370693219277f0c3a209', '151', 'BankAction', DEFAULT, DEFAULT, DEFAULT, '3671', '45', 0, '435491', '435491', DEFAULT, DEFAULT, DEFAULT, 'iran_khodro_bank_action_transfer_order_nested', '{\"for\":null,\"description\":null}', DEFAULT, DEFAULT, '2021-11-16 16:58:41.000', '2021-11-16 16:58:41.000')
2021-11-16T13:28:41.167351Z 382 Connect root@172.18.0.1 on loyalty using TCP/IP
2021-11-16T13:28:41.167577Z 382 Query START TRANSACTION
2021-11-16T13:28:41.168253Z 382 Query INSERT INTO `transactions`(`id`, `from_account_id`, `to_account_id`, `order_id`, `amount`, `split`, `reverse`, `revoked`, `created_at`, `updated_at`) VALUES (DEFAULT, '515723', '435491', '110687', 1100, DEFAULT, DEFAULT, DEFAULT, '2021-11-16 16:58:41.000', '2021-11-16 16:58:41.000')
解决方案
推荐阅读
- python - 在询问“分离源和构建目录”后,Sphinx-quickstart 中止
- c++ - 尝试使用 cURL 时出现多个错误
- gwt - 在 Web 组件中包装 GWT 小部件
- variables - 堆栈上的变量是否由垃圾收集器收集?
- python - 使用 loc、iloc 和检查条件访问 pandas 中的单元格值
- image - 我正在使用 image_picker 从画廊和相机中获取图像,但尺寸太小
- python - 熊猫“描述”和“描述()”有什么区别?
- css-selectors - 对所有文件应用 svelte-ignore 警告注释
- python - 使用 python-pandas 实现 SQL“MERGE INTO”命令的最佳方法?
- c++ - 在 C++ 中嗅探