-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Add a default lock mode to the EntityManager #949
base: old-prototype-3.x
Are you sure you want to change the base?
Conversation
Hello, thank you for creating this pull request. I have automatically opened an issue http://www.doctrine-project.org/jira/browse/DDC-2973 We use Jira to track the state of pull requests and the versions they got |
@@ -102,7 +102,7 @@ class SqlWalker implements TreeWalker | |||
private $conn; | |||
|
|||
/** | |||
* @var \Doctrine\ORM\AbstractQuery | |||
* @var \Doctrine\ORM\Query |
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.
This is always a Query
as far as I can see in the code, and the passing tests seem to confirm that.
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.
If that is really true, can you please remove the false
check in this line? I added that with my last modification because I was not sure whether it always is Query
and $this->query->getHint(Query::HINT_LOCK_MODE)
which you replaced could return false
.
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.
No problem, as soon as it's confirmed by one of the lead developers!
Hey @BenMorel, Sorry for not giving you feedback in time. The patch looks simple and clean, and it is a nice feature addition for the amount of code that it carries. Do you think that it would be possible to add functional tests for it? |
Hi @Ocramius, thanks for your reply! I have added a bunch of tests to cover all the use cases mentioned above:
They all test that the generated SQL query ends (or not) with the Note: I had to add functionality to existing mocks, but without breaking any existing tests. |
One more thing, I'm still not sure about the As explained above, it feels a tiny bit wrong as I think the configuration should be kept for things that are not likely to change after bootstrapping, whereas the default lock mode is something that will change from controller to controller within the same application. So I would like to suggest two different approaches:
I quite like the second approach, as it does not make sense (correct me if I'm wrong) to set a lock mode outside a transaction; so we could set a default lock mode that is valid only for the current transaction, and without breaking the existing API. It feels more intuitive this way. It would be nice to get the opinion of @beberlei, @FabioBatSilva, @guilhermeblanco, @jwage, @asm89, @stof on this point? |
I am against this kind of "global" state. It can lead to very confusing side effects. I would rather have a closure that wraps everything in this kind of lock mode and then disables after commit. This is something for the transaction object that @guilhermeblanco is always talking about :) |
@beberlei Thanks for your comment, but what about the third approach then:
It's possible straight away even without a transaction object, does not break the API, and would only be valid for this transaction! I'm happy to update the code with a proof of concept if you wish to see it implemented. |
@BenMorel I would be very happy. |
@guilhermeblanco I would be happy to help further with the transaction object, but to be honest I don't think I have enough knowledge on the subject to be able to start any work on it right now; I was just proposing to move the default lock mode setting to That being said, I'm happy to discuss this with you further tomorrow! |
Ok I've played a bit more with it, and it looks like it will be a little bit hacky to do it that way, and indeed @beberlei is right, this would fit the idea of transaction objects very well. I would like to give transaction objects a go, and reading a little bit about them, I think we could start with something really simple, that would just encapsulate the I'm happy to open another PR with a proof of concept on the DBAL first - and leave this PR on hold for now -, but I need to confirm first with @beberlei that it would be acceptable to:
I know that you're meticulously following semver and I don't know how that would translate in terms of bumping versions. I truly hope that it could fit the next minor version, as this would potentially break no project using Doctrine as is, unless the project uses a custom Connection subclass, but I can't see any real life use case for this (I might be wrong). Please let me know what you think, I'd be happy to give it a go ASAP! |
@beberlei I'm actually already seeing inconsistencies in the API:
|
@BenMorel Why not:
We keep BC and we also add our own support. |
@guilhermeblanco That's where I get lost :-) Why storing data inside of Transaction? My idea was to simply encapsulate the current behaviour in a Transaction object: underlying database transaction, savepoints, and "rollback only" flag. Do I miss something? Otherwise, I like the idea of adding |
Ok I've starting playing around with this idea, and here is the result: doctrine/dbal#571 I have no idea if it's what you had in mind guys, it can be miles away, but hopefully it's close. I personally like it, it really de-clutters the And if we were going that route, I could add a configuration to the
The Please let me know what you think by commenting on doctrine/dbal#571! Note: I didn't add the default lock mode or any kind of configuration yet on the Transaction object, to keep things simple while the draft is being reviewed. This would be the subject of yet another PR on the DBAL. |
Can we also have the events after the transaction is really commited. |
@mvrhov You should open a separate issue for this! |
Ok, I think we're getting somewhere with the transaction object in doctrine/dbal#634:
My only issue now is: how do we add configuration options specific to the ORM? The I've thought about a generic API for setting any variable:
This way, we don't have to extend any classes in the ORM. We just have to define configuration constants in the The DBAL would get the isolation level of the transaction with:
The ORM would get the default lock mode of the transaction with:
What do you think? |
@BenMorel getting back to this: does this require evaluation of doctrine/dbal#634 first? |
@Ocramius Yes, we would need doctrine/dbal#634 merged first! |
4532b88
to
c064458
Compare
@Ocramius Is there anything preventing this PR (and doctrine/dbal#634) from being merged now? It's been 18 months already, and that would be a nice new feature for Doctrine 2.6. |
@BenMorel Sort of out of left-field here, but I'm working on #1456 which might end up involving a new mode |
@DHager Worst case scenario, we could prevent setting the default lock mode to |
@BenMorel Most likely. I don't think it's a big deal since it won't matter |
Guys, it's been 2 years since I opened this pull request, but nobody seems to care, neither on this PR, nor on doctrine/dbal#634 it depends on. I'm not far from abandoning them due to the lack of feedback. It's a pity, as it is a feature I needed and still need. |
Up. 😑 |
Bump 😢 |
I know the feeling. |
Well, this PR depend on a DBAL PR which is not merged, so it has no way to be merged |
Aren't the maintainers of ORM and DBAL the same people ? |
Are you still interested in merging this feature, should I rebase it on 3.0? |
If the Transaction object lands in DBAL, i think some similar approach around it here would be better than global switches. |
@Majkl578 That's exactly why I'm trying to push the Transaction object into DBAL first 👍 Basically calling |
We could probably think about some high-level transaction abstraction in ORM (more like business transactions) and completely shadow the DBAL in there. Just a thought though. |
That could be an idea. We don't actually need to expose the DBAL transaction at all, we can encapsulate it privately. |
Exactly, and locking could sit just on top of all that. JPA defines things like EntityTransaction or resource-local EMs or JTA EMs. That may be an interesting approach, if architecturally possible. |
Let's focus on the Transaction object then, and I'll make a proposal of an ORM transaction here :) |
Following this discussion on the mailing list, this proposal introduces a default lock mode for all entities loaded through an EntityManager.
At the moment, there is no way to set a lock mode for the following use cases:
getReference()
and then initializedThis proposal introduces the idea of a default lock mode, which can be set at runtime when all reads in a transaction should be locking.
It works this way:
I have successfully tested it with the following use cases:
EntityManager::find()
EntityRepository::findBy()
Happily waiting for your feedback!