Skip to content

Commit 83d7477

Browse files
committed
fix(db): use atomic INSERT ON CONFLICT instead of SELECT-then-INSERT
Eliminates race condition under READ COMMITTED isolation and fixes COALESCE sentinel mismatch between the unique index and the application-level query. Signed-off-by: Prem bharne <prembharne455@gmail.com>
1 parent 911022f commit 83d7477

1 file changed

Lines changed: 8 additions & 26 deletions

File tree

backend/src/database/repositories/memberSegmentAffiliationRepository.ts

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,36 +44,18 @@ class MemberSegmentAffiliationRepository extends RepositoryBase<
4444

4545
const transaction = this.transaction
4646

47-
const existing = await this.options.database.sequelize.query(
48-
`SELECT "id" FROM "memberSegmentAffiliations"
49-
WHERE "memberId" = :memberId
50-
AND "segmentId" = :segmentId
51-
AND "organizationId" IS NOT DISTINCT FROM :organizationId
52-
AND "dateStart" IS NOT DISTINCT FROM :dateStart
53-
AND "dateEnd" IS NOT DISTINCT FROM :dateEnd
54-
LIMIT 1`,
55-
{
56-
replacements: {
57-
memberId: data.memberId,
58-
segmentId: data.segmentId,
59-
organizationId: data.organizationId,
60-
dateStart: data.dateStart || null,
61-
dateEnd: data.dateEnd || null,
62-
},
63-
type: QueryTypes.SELECT,
64-
transaction,
65-
}
66-
)
67-
68-
if (existing.length > 0) {
69-
await this.updateAffiliation(data.memberId, data.segmentId, data.organizationId)
70-
return this.findById((existing[0] as any).id)
71-
}
72-
7347
const affiliationInsertResult = await this.options.database.sequelize.query(
7448
`INSERT INTO "memberSegmentAffiliations" ("id", "memberId", "segmentId", "organizationId", "dateStart", "dateEnd")
7549
VALUES
7650
(:id, :memberId, :segmentId, :organizationId, :dateStart, :dateEnd)
51+
ON CONFLICT (
52+
"memberId",
53+
"segmentId",
54+
COALESCE("organizationId", '00000000-0000-0000-0000-000000000000'::uuid),
55+
COALESCE("dateStart", '1970-01-01T00:00:00Z'::timestamptz),
56+
COALESCE("dateEnd", '1970-01-01T00:00:00Z'::timestamptz)
57+
)
58+
DO UPDATE SET "organizationId" = EXCLUDED."organizationId"
7759
RETURNING "id"
7860
`,
7961
{

0 commit comments

Comments
 (0)