Enable optimistic locking using an ObjectId as version field#2815
Enable optimistic locking using an ObjectId as version field#2815GromNaN merged 2 commits intodoctrine:2.13.xfrom
ObjectId as version field#2815Conversation
There was a problem hiding this comment.
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
Versionableinterface forObjectIdTypewith agetNextVersion()method - Adds comprehensive test coverage for the new versioning capability
- Updates documentation to include
object_idas 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
| """"""""""""""""""""""" | ||
|
|
||
| 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.
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.
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.
Exact, the ObjectIdType convert the ObjectId into a string. You have to convert it back to ObjectId to get the timestamp.
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.
| """"""""""""""""""""""" | ||
|
|
||
| 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.
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
versionfield that is incremented on each version.intfield is safe but doesn't provide any information about the last updatedatefield provides the last update date, but is not safe if updates occurs during the same millisecond.ObjectIdis perfect as it is both safe, sortable and provide the update date usingObjectId::getTimestamp()