Using strategy set on EmbedMany seems to call an unset then set #434

Closed
andrewjshults opened this Issue Oct 19, 2012 · 5 comments

Projects

None yet

4 participants

@andrewjshults

Been trying to debug some really weird race condition issues that happen when a bunch of AJAX actions are fired off. The AJAX call passes in a new array of recipients to add onto an RFP object. We setup a logger on the Doctrine mongo connection. The expected action is that it would simply call set, what seems to happen is that it first calls unset on the field and then call set with the correct data. Since mongo isn't transactional, this opens up the (very real) possibility that another thread will read the data in between the unset and set calls (where the data is missing). The default pushAll strategy does the same - the issue remains the same, but removing the unset would break the expected behavior (even doing a diff and setting/unsetting array elements would be subject to issues where the incorrect elements could be unset if the document had been updated in between the read and flush events).

From looking at the code, the set strategy seems to be the only one that would be safe from a race condition (although, we are still seeing multiple set queries for the same object within the same flush), as long as the unset is dropped. Trying to understand the logic behind including it to make sure that we're not going to break something else by removing it.

Also, the set and pushAll strategies seem to save the EmbedMany ArrayCollections in different formats - pushAll as an array and set as a hash (with integers stored as strings for keys). We're currently using the default pushAll strategy but plan to convert to the set strategy to (partially) solve this race condition.

Array
(
    [update] => 1
    [query] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 5080abcfd8ad73b13a000000
                )

        )

    [newObj] => Array
        (
            [$unset] => Array
                (
                    [recipients] => 1
                )

        )

    [options] => Array
        (
            [safe] => 1
            [fsync] => 1
        )

    [db] => test
    [collection] => rfps
)
Array
(
    [update] => 1
    [query] => Array
        (
            [_id] => MongoId Object
                (
                    [$id] => 5080abcfd8ad73b13a000000
                )

        )

    [newObj] => Array
        (
            [$set] => Array
                (
                    [recipients] => Array
                        (
                            [0] => Array
                                (
                                    [name] =>  
                                    [email] => jeff@smith.com
                                    [contact] => Array
                                        (
                                            [$ref] => contacts
                                            [$id] => MongoId Object
                                                (
                                                    [$id] => 507ebffb4cd844af6e6873bc
                                                )

                                            [$db] => adstruc
                                        )

                                    [created] => MongoDate Object
                                        (
                                            [sec] => 1350611713
                                            [usec] => 0
                                        )

                                )

                            [1] => Array
                                (
                                    [name] =>  
                                    [email] => bob@bobdole.net
                                    [contact] => Array
                                        (
                                            [$ref] => contacts
                                            [$id] => MongoId Object
                                                (
                                                    [$id] => 507ebffb4cd844af6e6873bd
                                                )

                                            [$db] => adstruc
                                        )

                                    [created] => MongoDate Object
                                        (
                                            [sec] => 1350611713
                                            [usec] => 0
                                        )

                                )

                        )

                )

        )

    [options] => Array
        (
            [safe] => 1
            [fsync] => 1
        )

    [db] => adstruc
    [collection] => rfps
)
@jwage
Doctrine member

Are you dereferencing the embedded many collection in PHP by resetting it with a new array or new ArrayCollection?

@andrewjshults
@Narretz

This also happens should you use a setter with ReferenceMany.

@malarzm
Doctrine member

Just to cross reference the issue will be fixed once #1120 is merged, also to help highly concurrent applications we have introduced atomicSet and atomicSetArray startegies for collections :)

@malarzm malarzm added the bug label Jun 7, 2015
@malarzm malarzm added this to the 1.0.0-BETA14 milestone Jun 7, 2015
@malarzm malarzm added the has PR label Jun 8, 2015
@malarzm malarzm modified the milestone: 1.0.0-BETA14, 1.0.0 Jun 11, 2015
@malarzm
Doctrine member

#1120 was merged manually in c06e8d4

@malarzm malarzm closed this Jun 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment