DDC-1306: Possible bug in CommitOrderCalculator #1920

Closed
doctrinebot opened this Issue Jul 30, 2011 · 3 comments

2 participants

@doctrinebot

Jira issue originally created by user arthens:

(I'm not sure it's a bug, it might be the way I configured Doctrine)

Sometime Doctrine fails to calculate the right commit order, and then it fails when flushing because some db constraints are failing. I hacked the CommitOrderCalculator so that it would print the list of the dependencies, and this is what I found:
(I don't have time to write code now, so I'll try to explain it with words. If it's not clear I'll find some time tomorrow to hack together a test)

Let's say that we have the class User. The class user is connected to other classes (News, Comment, Post) with an unidirectional relation, so that User doesn't know anything about the other class.

Let's say we create a User and we save it. The CommitOrderCalculator will calculate the dependencies on User. This is a partial list, some dependencies won't be there (not sure whether it's because they haven't been loaded yet, whether it's because they are not part of the UnitOfWork or whether it's because User doesn't know about them) *****

Let's say that later, in the same request, we create a News. CommitOrderCalculator will calculate the dependencies for News. However, for User it will use the cached dependencies, and it won't realize that now User is required for News.

***** Could it be a configuration problem?
Are the dependencies supposed to be incomplete? (it seems reasonable as long as they are calculated for a single UnitOfWork, but it seems wrong if the dependencies are shared with multiple transactions)
Or am I loading the classes in the wrong way?

Code references:
UnitOfWork::getCommitOrder line 840
The class is added to $newNodes (the array used to calculate dependencies) only if the CommitOrderCalculator doesn't know the class already

CommitOrderCalculator::getCommitOrder line 83
After getting the order *sorted and _nodeStates are reset, while _classes and *relatedClasses are not.

Basically UnitOfWork register the class only once, and CommitOrderCalculator doesn't forget about the class when the UnitOfWork ends.

Possible fix:

  • Resetting *classes and *relatedClasses seem to fix the problem, but I don't know what was the rationale for not doing it, so I'm unclear whether it's the right think or not.

Example:
Dependencies calculated with the current code
Visiting Users\Model\User
Forum\Model\Forum
Visiting Forum\Model\Forum
Forum\Model\Forum
Forum\Model\Topic
Visiting Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Topic
Visiting Forum\Model\Post
Forum\Model\Forum
Forum\Model\Topic
Forum\Model\Topic

Dependencies calculated with the reset
Visiting Forum\Model\Topic
Forum\Model\Post
Visiting Forum\Model\Post
Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Forum
Visiting Forum\Model\Forum
Forum\Model\Topic
Forum\Model\Forum
Visiting Users\Model\User
Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Post
Forum\Model\Post

  • Forum\Model\Forum
@doctrinebot

Comment created by @beberlei:

Verified.

The Calculator is only populated partially because otherwise it had to calculate the dependencies for all classes all the time, caused through a riffle effect.

@doctrinebot

Comment created by @beberlei:

Fixed

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.1.2 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment