{"record":{"id":"20b8fd8a0a191a75","repo":"quarkusio/quarkus","slug":"write-lock-not-acquired-in-time-ms","errorCode":null,"errorMessage":"Write lock not acquired in ${time} ms","messagePattern":"Write lock not acquired in (.+?) ms","errorType":"exception","errorClass":"jakarta.enterprise.context.control.LockException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/LockInterceptor.java","lineNumber":61,"sourceCode":"        long time = lock.time();\n        int readHoldCount = rwl.getReadHoldCount();\n        boolean locked = false;\n\n        try {\n            if (readHoldCount > 0) {\n                rl.lock();\n            }\n            try {\n                if (readHoldCount > 0) {\n                    // Release all read locks hold by the current thread before acquiring the write lock\n                    for (int i = 0; i < readHoldCount; i++) {\n                        rwl.readLock().unlock();\n                    }\n                }\n                if (time > 0) {\n                    locked = rwl.writeLock().tryLock(time, lock.unit());\n                    if (!locked) {\n                        throw new LockException(\"Write lock not acquired in \" + lock.unit().toMillis(time) + \" ms\");\n                    }\n                } else {\n                    rwl.writeLock().lock();\n                    locked = true;\n                }\n            } finally {\n                if (readHoldCount > 0) {\n                    rl.unlock();\n                }\n            }\n            return ctx.proceed();\n        } finally {\n            if (locked) {\n                if (readHoldCount > 0) {\n                    // Re-aqcquire the read locks\n                    for (int i = 0; i < readHoldCount; i++) {\n                        rwl.readLock().lock();\n                    }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/LockInterceptor.java#L43-L79","documentation":"When @Lock(WRITE) is used with time > 0, LockInterceptor tries rwl.writeLock().tryLock(time, unit); if the lock is not obtained within that time it throws LockException. The write lock is held by another thread for longer than the configured timeout, so the guarded business method could not run.","triggerScenarios":"Method annotated @Lock(value = WRITE, time = N, unit = X) while another thread holds (or waits on) the same bean's write/read lock longer than N units; time > 0 makes the wait bounded and fails fast instead of blocking forever.","commonSituations":"Long-running write operations under high concurrency; deadlock/livelock between read and write callers; time set too low for slow I/O inside the locked method; same bean called re-entrantly from a thread already holding the read lock (readers cannot upgrade to writer).","solutions":["Increase lock.time()/unit on the @Lock annotation to a realistic bound.","Shrink the work performed inside the write-locked method (move slow I/O outside the lock).","Investigate the competing holder — log or dump threads to find a deadlock or long read-holders.","Avoid read→write lock upgrade patterns (release the read lock before requesting write).","If unbounded waiting is acceptable, set time = 0 so writeLock().lock() blocks indefinitely instead of throwing."],"exampleFix":"// before\n@Lock(value = LockType.WRITE, time = 100, unit = TimeUnit.MILLISECONDS)\npublic void sync() { heavyNetworkCall(); }\n// after\n@Lock(value = LockType.WRITE, time = 5, unit = TimeUnit.SECONDS)\npublic void sync() { heavyNetworkCall(); }","handlingStrategy":"retry","validationCode":"// size the timeout to worst-case work: measure the write path before fixing lock.time()\nlong measuredMs = measure(writeOperation);\nif (measuredMs >= unit.toMillis(time)) { log.warn(\"@Lock(WRITE) time too small: \" + measuredMs + \"ms\"); }","typeGuard":null,"tryCatchPattern":"try {\n    return bean.writeOperation();\n} catch (LockException e) {\n    // bounded wait expired: back off and retry or degrade\n    Thread.sleep(retryBackoffMs);\n    return bean.writeOperation();\n}","preventionTips":["Keep work inside @Lock(WRITE) methods short and free of slow I/O","Set generous-but-bounded lock.time values based on measured worst case","Watch for read→write lock upgrade patterns that self-deadlock","Under load, monitor lock contention before tightening timeouts"],"tags":["locking","concurrency","timeout","arc"],"backgroundTag":"lock-acquisition-timeout","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-15T02:17:10.978Z"}