Skip to content

Conversation

GromNaN
Copy link
Member

@GromNaN GromNaN commented Sep 1, 2025

Q A
Type feature
BC Break no
Fixed issues Related to #2789

Summary

Optimistic Locking use a version field that is incremented on each version.

  • Using a int field is safe but doesn't provide any information about the last update
  • Using a date field provides the last update date, but is not safe if updates occurs during the same millisecond.
  • Using an a MongoDB ObjectId is perfect as it is both safe, sortable and provide the update date using ObjectId::getTimestamp()

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for using MongoDB ObjectId as a version field for optimistic locking. This provides a unique, sortable identifier that includes timestamp information while maintaining safety from concurrent updates.

  • Implements the Versionable interface for ObjectIdType with a getNextVersion() method
  • Adds comprehensive test coverage for the new versioning capability
  • Updates documentation to include object_id as a supported versioning type

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
lib/Doctrine/ODM/MongoDB/Types/ObjectIdType.php Implements Versionable interface and adds getNextVersion() method
tests/Doctrine/ODM/MongoDB/Tests/Types/VersionableTest.php Adds test coverage for all versionable types including new ObjectId support
docs/en/reference/transactions-and-concurrency.rst Updates documentation to list object_id as supported versioning type

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@GromNaN GromNaN force-pushed the versional-object-id branch from 5159cd6 to f4b6e9e Compare September 1, 2025 17:02
@@ -190,7 +190,7 @@ Choosing the Field Type
"""""""""""""""""""""""

When using the date-based type in a high-concurrency environment, it is still possible to create multiple documents
with the same version and cause a conflict. This can be avoided by using the ``int`` or ``decimal128`` type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Honestly think it would be worth explicitly mentioning somewhere the possibility of deriving the timestamp from the object ID. It's quite a good idea and will probably not occur to many users unless it's mentioned somewhere.

Copy link
Member

Choose a reason for hiding this comment

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

IIRC, ODM converts ObjectId values to strings, so users won't be able to easily utilize ObjectId::getTimestamp() for that purpose. Perhaps this would warrant a separate tutorial or cookbook entry, as there's likely a bit more code involved to parse the timestamp from the string (could be done with PHP code separate from ext-mongodb).

On a separate note, ObjectIds might also encounter issues in high-concurrency environments (see: SERVER-6054). The 4-byte timestamp and 3-byte counter (see: ObjectId spec) likely provides more uniqueness than a UTCDateTime with millisecond precision, though.

Copy link
Member Author

Choose a reason for hiding this comment

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

Exact, the ObjectIdType convert the ObjectId into a string. You have to convert it back to ObjectId to get the timestamp.

return $value !== null ? (string) $value : null;

ObjectIds might also encounter issues in high-concurrency environments
A max of 16 millions unique ObjectId per second should be more than what a single PHP process can handle.

@@ -190,7 +190,7 @@ Choosing the Field Type
"""""""""""""""""""""""

When using the date-based type in a high-concurrency environment, it is still possible to create multiple documents
with the same version and cause a conflict. This can be avoided by using the ``int`` or ``decimal128`` type.
Copy link
Member

Choose a reason for hiding this comment

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

IIRC, ODM converts ObjectId values to strings, so users won't be able to easily utilize ObjectId::getTimestamp() for that purpose. Perhaps this would warrant a separate tutorial or cookbook entry, as there's likely a bit more code involved to parse the timestamp from the string (could be done with PHP code separate from ext-mongodb).

On a separate note, ObjectIds might also encounter issues in high-concurrency environments (see: SERVER-6054). The 4-byte timestamp and 3-byte counter (see: ObjectId spec) likely provides more uniqueness than a UTCDateTime with millisecond precision, though.

@GromNaN GromNaN merged commit 6072551 into doctrine:2.13.x Sep 3, 2025
22 checks passed
@GromNaN GromNaN deleted the versional-object-id branch September 3, 2025 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants