Skip to content

Commit

Permalink
fix(core): Add retry logic in case of transaction deadlocks
Browse files Browse the repository at this point in the history
Fixes #527.
  • Loading branch information
michaelbromley committed Nov 4, 2020
1 parent fc3890e commit 3b60bcb
Show file tree
Hide file tree
Showing 8 changed files with 5,080 additions and 4,397 deletions.
86 changes: 86 additions & 0 deletions packages/core/e2e/fixtures/test-plugins/slow-mutation-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import {
Asset,
AssetType,
Country,
Ctx,
PluginCommonModule,
Product,
ProductAsset,
RequestContext,
TaxCategory,
TaxRate,
Transaction,
TransactionalConnection,
VendurePlugin,
} from '@vendure/core';
import gql from 'graphql-tag';

@Resolver()
export class SlowMutationResolver {
constructor(private connection: TransactionalConnection) {}

/**
* A mutation which simulates some slow DB operations occurring within a transaction.
*/
@Transaction()
@Mutation()
async slowMutation(@Ctx() ctx: RequestContext, @Args() args: { delay: number }) {
const delay = Math.round(args.delay / 2);
const country = await this.connection.getRepository(ctx, Country).findOneOrFail({
where: {
code: 'AT',
},
});
country.enabled = false;
await new Promise(resolve => setTimeout(resolve, delay));
await this.connection.getRepository(ctx, Country).save(country);
country.enabled = true;
await new Promise(resolve => setTimeout(resolve, delay));
await this.connection.getRepository(ctx, Country).save(country);
return true;
}

/**
* This mutation attempts to cause a deadlock
*/
@Transaction()
@Mutation()
async attemptDeadlock(@Ctx() ctx: RequestContext) {
const product = await this.connection.getRepository(ctx, Product).findOneOrFail(1);
const asset = await this.connection.getRepository(ctx, Asset).save(
new Asset({
name: 'test',
type: AssetType.BINARY,
mimeType: 'test/test',
fileSize: 1,
source: '',
preview: '',
}),
);
await new Promise(resolve => setTimeout(resolve, 100));
const productAsset = await this.connection.getRepository(ctx, ProductAsset).save(
new ProductAsset({
assetId: asset.id,
productId: product.id,
position: 0,
}),
);
await this.connection.getRepository(ctx, Product).update(product.id, { enabled: false });
return true;
}
}

@VendurePlugin({
imports: [PluginCommonModule],
adminApiExtensions: {
resolvers: [SlowMutationResolver],
schema: gql`
extend type Mutation {
slowMutation(delay: Int!): Boolean!
attemptDeadlock: Boolean!
}
`,
},
})
export class SlowMutationPlugin {}
Loading

0 comments on commit 3b60bcb

Please sign in to comment.