Skip to content

Add support for MySQL 8.0.1+ locking features (FOR SHARE, NOWAIT, SKIP LOCKED) #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: maint/0.0828xx
Choose a base branch
from

Conversation

StefanStuehrmann
Copy link

Overview

This PR enhances DBIx::Class's MySQL support by implementing the locking features introduced in MySQL 8.0.1:

  • Adds support for the standard SQL-compliant FOR SHARE syntax (while maintaining backward compatibility with LOCK IN SHARE MODE)
  • Implements NOWAIT modifier to fail immediately when encountering locked rows
  • Implements SKIP LOCKED modifier to skip locked rows in the result set
  • Adds support for the OF table_name clause to lock specific tables

[https://dev.mysql.com/blog-archive/mysql-8-0-1-using-skip-locked-and-nowait-to-handle-hot-rows/]

Implementation Details

The implementation introduces a flexible hash-based configuration for advanced locking options while maintaining backward compatibility with the existing string-based syntax:

# Basic usage (existing functionality)
$rs->find({...}, {for => 'update'});

# New standard shared lock (MySQL 8.0.1+)
$rs->find({...}, {for => 'share'});

# Advanced locking with modifiers
$rs->find({...}, {
  for => {
    type => 'update',
    modifier => 'nowait'
  }
});

# Locking specific tables
$rs->find({...}, {
  for => {
    type => 'share',
    of => ['table1', 'table2'],
    modifier => 'skip_locked'
  }
});

A deprecation warning has been added for the legacy shared option to encourage migration to the new standard share option.

Testing

Comprehensive test coverage has been added for all locking features, including:

  • Basic locking options
  • Hash-based configuration
  • Modifiers (NOWAIT, SKIP LOCKED)
  • Table specification with the OF clause
  • Combinations of modifiers and table specifications

Motivation

These locking features are essential for building robust concurrent applications with MySQL 8.0.1+. The NOWAIT and SKIP LOCKED options are particularly valuable for implementing job queues and other high-concurrency patterns like exact once processing and helps avoiding deadlocks or long waits.

This commit enhances the MySQL SQLMaker to support the new locking features
introduced in MySQL 8.0.1:

- Add support for the new standard SQL-compliant 'FOR SHARE' syntax
  (while maintaining backward compatibility with 'LOCK IN SHARE MODE')
- Add support for 'NOWAIT' modifier to fail immediately on locked rows
- Add support for 'SKIP LOCKED' modifier to skip locked rows
- Add support for 'OF table_name' clause to lock specific tables

The implementation allows for both simple string syntax for basic locking
and a more flexible hash-based configuration for advanced locking options.

Example usage:
- Basic: {for => 'share'}
- Advanced: {for => {type => 'update', modifier => 'nowait', of => ['table1']}}

A deprecation warning is added for the legacy 'shared' option to encourage
migration to the new standard 'share' option.
This commit adds test coverage for both existing and new MySQL locking features:

Existing features:
- Basic locking with 'for => "update"'
- Legacy shared locking with 'for => "shared"' (with warning suppression)

New features (MySQL 8.0.1+):
- Standard SQL-compliant shared locking with 'for => "share"'
- Hash-based configuration for advanced locking options:
  - NOWAIT modifier to fail immediately on locked rows
  - SKIP LOCKED modifier to skip locked rows
  - OF clause to lock specific tables
  - Combinations of modifiers and table specifications

The tests verify that the SQL generated for each locking option is correct,
ensuring that the implementation works as expected across all supported
locking features.
@StefanStuehrmann
Copy link
Author

@ribasushi any chance you can review this change please? There are a lot of threaded / worker based applications out there relying on mysql so this feature allows to improve them without major redesign to become active/active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant