-
-
Notifications
You must be signed in to change notification settings - Fork 513
Enable optimistic locking using an ObjectId
as version field
#2815
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
Conversation
There was a problem hiding this 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 forObjectIdType
with agetNextVersion()
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.
5159cd6
to
f4b6e9e
Compare
f4b6e9e
to
650b14d
Compare
@@ -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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
Summary
Optimistic Locking use a
version
field that is incremented on each version.int
field is safe but doesn't provide any information about the last updatedate
field provides the last update date, but is not safe if updates occurs during the same millisecond.ObjectId
is perfect as it is both safe, sortable and provide the update date usingObjectId::getTimestamp()