Skip to content

Instantly share code, notes, and snippets.

View alphamikle's full-sized avatar

Mike Alfa alphamikle

View GitHub Profile
START TRANSACTION
// ...
SELECT "Purse"."id" AS "Purse_id", "Purse"."balance" AS "Purse_balance", "Purse"."userId" AS "Purse_userId"
FROM "purse" "Purse"
WHERE "Purse"."id" IN ($1)
START TRANSACTION
SELECT "Purse"."id" AS "Purse_id", "Purse"."balance" AS "Purse_balance", "Purse"."userId" AS "Purse_userId"
FROM "purse" "Purse"
WHERE "Purse"."id" IN ($1)
UPDATE "purse"
START TRANSACTION
// ...
SELECT "Purse"."id" AS "Purse_id", "Purse"."balance" AS "Purse_balance", "Purse"."userId" AS "Purse_userId"
FROM "purse" "Purse"
WHERE "Purse"."id" IN ($1)
START TRANSACTION
SELECT "Purse"."id" AS "Purse_id", "Purse"."balance" AS "Purse_balance", "Purse"."userId" AS "Purse_userId"
FROM "purse" "Purse"
WHERE "Purse"."id" IN ($1)
UPDATE "purse"
// ..
@Transaction()
async savePurseInTransaction(purse: Purse, @TransactionManager() transactionManager: EntityManager = null) {
await transactionManager.save(Purse, purse);
}
// ...
// ...
@Transaction() // <-- this
async makeRemittanceWithTypeOrmV2(fromId: number, toId: number, sum: number, withError: boolean, @TransactionManager() transactionEntityManager: EntityManager = null /* <-- and this */) {
const fromUser = await transactionEntityManager.findOne(User, fromId);
const toUser = await transactionEntityManager.findOne(User, toId);
if (fromUser === undefined) {
throw new Error(NOT_FOUND_USER_WITH_ID(fromId));
}
if (toUser === undefined) {
throw new Error(NOT_FOUND_USER_WITH_ID(toId));
// ...
@Post('remittance-with-typeorm-transaction-decorators')
@ApiResponse({
type: RemittanceResultDto,
})
async makeRemittanceWithTypeOrmTransactionDecorators(@Body() remittanceDto: RemittanceDto) {
return this.appService.makeRemittanceWithTypeOrmV2(remittanceDto.userIdFrom, remittanceDto.userIdTo, remittanceDto.sum, remittanceDto.withError);
}
// ...
START TRANSACTION
// ...
SELECT "Purse"."id" AS "Purse_id", "Purse"."balance" AS "Purse_balance", "Purse"."userId" AS "Purse_userId"
FROM "purse" "Purse"
WHERE "Purse"."id" IN ($1)
START TRANSACTION
UPDATE "purse"
SET "balance" = $2
WHERE "id" IN ($1)
COMMIT
START TRANSACTION
// ...
SELECT "User"."id" AS "User_id", "User"."name" AS "User_name", "User"."defaultPurseId" AS "User_defaultPurseId"
FROM "user" "User"
WHERE "User"."id" IN ($1)
START TRANSACTION // <-- this transaction from appServiceV2 😩
UPDATE "purse"
SET "balance" = $2
WHERE "id" IN ($1)
COMMIT
@Injectable()
export class AppServiceV2 {
constructor(
@InjectRepository(Purse)
private readonly purseRepository: Repository<Purse>,
) {
}
async savePurse(purse: Purse) {
await this.purseRepository.save(purse);
}
async makeRemittanceWithTypeOrmV1(transactionEntityManager: EntityManager, fromId: number, toId: number, sum: number, withError = false) {
const fromUser = await transactionEntityManager.findOne(User, fromId); // <-- we need to use only provided transactionEntityManager, for make all requests in transaction
const toUser = await transactionEntityManager.findOne(User, toId); // <-- and there
if (fromUser === undefined) {
throw new Error(NOT_FOUND_USER_WITH_ID(fromId));
}
if (toUser === undefined) {
throw new Error(NOT_FOUND_USER_WITH_ID(toId));
}
if (fromUser.defaultPurseId === null) {
@Controller()
@ApiTags('app')
export class AppController {
constructor(
private readonly appService: AppService,
private readonly connection: Connection, // <-- it is - what we need
) {
}
// ...
}