Skip to content

[Messenger] Doctrine transport does nothing to prevent race conditions when using sqlsrv DBAL driver #39117

Closed
@thsmrtone1

Description

@thsmrtone1

Symfony version(s) affected: symfony/messenger:^4.4

Description
When Doctrine DBAL is set up to use SQL Server, and multiple message consumers are listening on the same doctrine transport, a message can be handled by more than one consumer simultaneously. It appears as though the DBAL platform getWriteLockSQL() method that the Messenger connection uses does not have compatibility with SQLServerPlatform (simply returns an empty string).

How to reproduce

  • Doctrine DBAL with sqlsrv connection
  • Many message consumers on the same doctrine transport/bus (tested with 5)

Possible Solution
Unknown if this can be fixed nor if there is a workaround. May need some documentation to explain the limitations.

Additional context
Queries that are executed as captured in logs:

[2020-11-19 15:08:24] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-11-19 15:08:24] doctrine.DEBUG: SELECT m.* FROM messenger_messages m WHERE (m.delivered_at is null OR m.delivered_at < ?) AND (m.available_at <= ?) AND (m.queue_name = ?) ORDER BY available_at ASC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY   ["2020-11-19 14:08:24","2020-11-19 15:08:24","default"] []
[2020-11-19 15:08:24] doctrine.DEBUG: UPDATE messenger_messages SET delivered_at = ? WHERE id = ? ["2020-11-19 15:08:24","7649"] []
[2020-11-19 15:08:24] doctrine.DEBUG: "COMMIT" [] []

^^ Notice there is no explicit lock on the select statement

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions