Skip to content

feat: Implement NoWait mechanism for database distributed lock#8111

Open
wushiyuanmaimob wants to merge 2 commits into
apache:2.xfrom
wushiyuanmaimob:perf/nowait-distributed-lock
Open

feat: Implement NoWait mechanism for database distributed lock#8111
wushiyuanmaimob wants to merge 2 commits into
apache:2.xfrom
wushiyuanmaimob:perf/nowait-distributed-lock

Conversation

@wushiyuanmaimob

Copy link
Copy Markdown

Summary

This PR implements the NoWait mechanism for database distributed locks to address issue #7993, resolving the TODO comment at line 150 in DataBaseDistributedLocker.

Problem: Under high concurrency (500+ TPS), the current SELECT ... FOR UPDATE blocks threads for 100-500ms when lock contention occurs, waiting for database lock timeout.

Solution: Introduce FOR UPDATE NOWAIT support for MySQL 8.0+, PostgreSQL, and Oracle, reducing lock contention latency to <1ms by failing fast instead of blocking.

Changes

  • SQL Dialect Support: Added MysqlDistributedLockSql, PostgresqlDistributedLockSql, and OracleDistributedLockSql with NOWAIT support
  • Interface Extension: Added getSelectDistributeForUpdateNoWaitSql() to DistributedLockSql interface with default fallback
  • Configuration Switch: Added store.db.distributedLockNoWaitEnabled (default false) for opt-in activation
  • Exception Handling: Extended ignoreSQLException() to recognize:
    • MySQL 8.0+ error code 3572 (ER_LOCK_NOWAIT)
    • PostgreSQL SQLState 55P03 (lock_not_available)
    • Oracle error code 54 (ORA-00054)
  • Backward Compatibility: Databases without NOWAIT support (SQL Server, MySQL 5.x, MariaDB) fall back to blocking behavior
  • Tests: Added comprehensive unit tests for SQL generation and exception handling

Test Plan

  • Core SQL factory tests pass (17 tests, 0 failures)
  • Spotless formatting check passes
  • New dialect implementations generate correct NOWAIT SQL
  • Default implementations fall back to blocking SQL
  • Exception handling correctly identifies NOWAIT error codes
  • Integration tests with real databases (MySQL 8.0+, PostgreSQL, Oracle) - requires dbCaseEnabled=true

Configuration

To enable NOWAIT on supported databases, add to application.yml:

store:
  db:
    distributedLockNoWaitEnabled: true

Note: Only enable on MySQL 8.0+, PostgreSQL, or Oracle. MySQL 5.x/MariaDB do not support NOWAIT and will raise syntax errors if enabled.

Related Issue

Resolves #7993

🤖 Generated with Claude Code

…ed lock

Under high concurrency (500+ TPS), blocking SELECT FOR UPDATE causes
threads to wait 100-500ms when lock contention occurs. This change
introduces NOWAIT support for MySQL 8.0+, PostgreSQL, and Oracle,
reducing lock contention latency to <1ms by failing fast instead of
blocking.

Changes:
- Add database dialect detection in DataBaseDistributedLocker
- Generate NOWAIT SQL for supported databases (MySQL/PostgreSQL/Oracle)
- Handle lock-busy exceptions gracefully (return false instead of throw)
- Maintain backward compatibility for databases without NOWAIT support
- Add configuration switch store.db.distributedLockNoWaitEnabled (default false)
- Extend ignoreSQLException to recognize MySQL 3572, PostgreSQL 55P03, Oracle 54
- Add comprehensive unit tests for NOWAIT SQL generation and exception handling

Resolves TODO comment at line 150 in DataBaseDistributedLocker.

Signed-off-by: sywu14 <wushiyuanwork@outlook.com>
@wushiyuanmaimob wushiyuanmaimob force-pushed the perf/nowait-distributed-lock branch from 0f9176a to 6635e80 Compare May 26, 2026 07:47
@WangzJi WangzJi changed the title [ISSUE #7993] Implement NoWait mechanism for database distributed lock feat: Implement NoWait mechanism for database distributed lock Jul 10, 2026
@WangzJi WangzJi requested a review from Copilot July 10, 2026 06:08
@WangzJi WangzJi added the type: feature Category issues or prs related to feature request. label Jul 10, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements an opt-in “NOWAIT” (fast-fail) acquisition path for the database-backed distributed lock, reducing thread blocking under high lock contention by using dialect-specific SELECT ... FOR UPDATE NOWAIT SQL and recognizing the corresponding vendor errors as expected contention signals.

Changes:

  • Adds getSelectDistributeForUpdateNoWaitSql() to DistributedLockSql with a default fallback to the blocking variant.
  • Introduces MySQL/PostgreSQL/Oracle distributed-lock SQL dialects that append FOR UPDATE NOWAIT, and wires DataBaseDistributedLocker to choose NOWAIT SQL when store.db.distributedLockNoWaitEnabled=true.
  • Extends ignoreSQLException() to treat NOWAIT contention signals (MySQL 3572, Oracle 54, PostgreSQL SQLState 55P03) as ignorable fast-fail outcomes, plus adds unit tests for SQL generation and exception matching.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
server/src/main/java/org/apache/seata/server/storage/db/lock/DataBaseDistributedLocker.java Adds config-driven NOWAIT path for lock-row selection and recognizes NOWAIT contention SQLExceptions.
server/src/test/java/org/apache/seata/server/storage/db/lock/DataBaseDistributedLockerTest.java Adds tests for NOWAIT exception handling and verifying NOWAIT vs blocking SQL usage.
core/src/main/java/org/apache/seata/core/store/db/sql/distributed/lock/DistributedLockSql.java Extends SPI with a default NOWAIT SQL method that falls back to legacy behavior.
core/src/main/java/org/apache/seata/core/store/db/sql/distributed/lock/MysqlDistributedLockSql.java MySQL dialect that generates FOR UPDATE NOWAIT.
core/src/main/java/org/apache/seata/core/store/db/sql/distributed/lock/PostgresqlDistributedLockSql.java PostgreSQL dialect that generates FOR UPDATE NOWAIT.
core/src/main/java/org/apache/seata/core/store/db/sql/distributed/lock/OracleDistributedLockSql.java Oracle dialect that generates FOR UPDATE NOWAIT.
core/src/main/resources/META-INF/services/org.apache.seata.core.store.db.sql.distributed.lock.DistributedLockSql Registers new dialect implementations for SPI discovery.
core/src/test/java/org/apache/seata/core/store/db/sql/distributed/lock/DistributedLockSqlNoWaitTest.java Adds unit tests validating dialect NOWAIT SQL and default fallback behavior.
core/src/test/java/org/apache/seata/core/store/db/sql/distributed/lock/DistributedLockSqlFactoryTest.java Updates factory tests to assert MySQL/PostgreSQL/Oracle map to the new dialect classes.
common/src/main/java/org/apache/seata/common/DefaultValues.java Adds default value for the new NOWAIT enablement configuration (disabled by default).
common/src/main/java/org/apache/seata/common/ConfigurationKeys.java Adds the store.db.distributedLockNoWaitEnabled configuration key.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +901 to +905
// Force the locker into nowait mode and switch its dbType so that
// the SPI returns a dialect with a real NOWAIT implementation.
setNowaitEnabled(locker, true);
setDbType(locker, "mysql");
setDistributedLockTable(locker, "distributed_lock");
Comment on lines +932 to +935
setNowaitEnabled(locker, false);
setDbType(locker, "mysql");
setDistributedLockTable(locker, "distributed_lock");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature Category issues or prs related to feature request.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposal] Implement "NoWait" Mechanism for DataBase Distributed Locking

3 participants