lock, SemaphoreSlim and ConcurrentDictionary protect only within a single process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // ====================================================================== // Q: The lock works on my machine but not in production with 3 pods. Why? // // lock, SemaphoreSlim and ConcurrentDictionary protect only within a single // process. With 3 pods there are 3 independent locks. The fix depends on the // problem: // - Data in the database: atomic UPDATE, unique constraint, optimistic // concurrency (Q60-Q61), FOR UPDATE SKIP LOCKED for job queues. // - "Only one instance runs the job": PostgreSQL advisory lock, a distributed // lock in Redis / Blob lease, or a Kubernetes CronJob. // - Duplicate messages: idempotency key / inbox (Q31). // ====================================================================== // Only one pod runs the nightly price import. The lock lives as long as the connection is open. await using var conn = await dataSource.OpenConnectionAsync(ct); await using var tryLock = new NpgsqlCommand("SELECT pg_try_advisory_lock(42)", conn); if (!(bool)(await tryLock.ExecuteScalarAsync(ct))!) return; // another pod is already running it try { await importer.RunAsync(ct); } finally { await using var unlock = new NpgsqlCommand("SELECT pg_advisory_unlock(42)", conn); await unlock.ExecuteNonQueryAsync(CancellationToken.None); } |