-
Notifications
You must be signed in to change notification settings - Fork 444
Description
The issue is that during a long or nested transaction, the sendUpdateIndexMessage()
is called during a postPersist
event, while the data may not yet be available in the database. The subsequent processing of the sent message (Doctrine/Queue/SyncIndexWithObjectChangeProcessor.php line 87) does not find the object and will send a delete command to Elastic instead of an insert.
This happens for example during a Doctrine fixtures load, which is actually several flushes inside nested transactions, but I have also seen it happen during a simple request (with queued processing). The problem is that the message is sent before the $conn->commit()
is done in the (outer-)transaction's flush call. So none of the Doctrine lifecycle events is gonna guarantee there will be no race conditions.
The solution imo is to allow the message to be delivered with a delay.
Activity
sneakyvv commentedon Jun 17, 2019
PR => php-enqueue/enqueue-elastica-bundle#19
aumel commentedon Jul 8, 2019
I encountered the same problem. I agree with @sneakyvv 's explanation. In PostPersist/PostUpdate, the DB transaction is not necessarily completed.
Unless I'm mistaken, there is indeed the usable
PostFlush
event. ThePostFlush
event is dispatched after the$conn->commit()
(see:UnitOfWork.php
).Doctrine doc:
In
SyncIndexWithObjectChangeListener.php
, we could do this:IMO, the solution with
PostFlush
is "safer" than the delay.sneakyvv commentedon Jul 8, 2019
Even the flush event cannot help during nested transactions. Every
flush()
is sending this event, but only the outer transaction really commits it to the database.So, I guess this is a Doctrine issue (too?).
aumel commentedon Jul 8, 2019
There are two problems (or contexts):
For the first problem, I think that enqueue-elastica should at least follow the implementation of FosElasticaBundle (see:
FOS\ElasticaBundle\Doctrine\Listener
) andsendUpdateIndexMessage
onPostFlush
.For the second, you're right. Doctrine events cannot help during nested transactions. It does not emit a
PostFlush
event in this case. You will encounter also this problem with FosElasticaBundle (without enqueue). You could dispatch thePostFlush
event yourself. Maybe this could be useful: doctrine/orm#7103 (comment).stale commentedon Aug 7, 2019
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.