MySQL Rows Inserted Twice

♀尐吖头ヾ 提交于 2020-01-16 19:37:07

问题


I am having some difficulty with MySQL seeming to insert a row twice. - Basically, I need to save a local copy of some information that is retrieved from a remote data source. So when a user views information that is from the remote source, I check to see if I have a local copy of the information I need to store. If I don't have a local copy I add a record of that information. - The issue I am having is that every I would say 20-30 inserts I get a duplicate. I keep track of the insert and update times using the NOW function, and both records seem to be inserted at the same time. Here is my PHP code, any help would be very appreciated, I am stumped:

// We have the location, see if we have a local record for that location
        $idLocation = locationID_for_factualID($factual_id);
        if(!$idLocation) {
            // We do not have local information about the location, add it
            $mysqli = open_mysql_connection();
            $stmt = $mysqli->prepare("INSERT INTO Location (
                                                    factual_id,
                                                    dateAdded, 
                                                    dateModified, 
                                                    locationName,
                                                    latitude, 
                                                    longitude) 
                                                VALUES (?, NOW(), NOW(), ?, ?, ?)");
            if($stmt) {
                $stmt->bind_param("ssdd",$factual_id, $location["name"], doubleval($location["latitude"]), doubleval($location["longitude"]));
                $stmt->execute();
                // Check if the location was added
                if($stmt->affected_rows == 1){
                    $idLocation = locationID_for_factualID($factual_id);
                }
                $stmt->close();
                $mysqli->close();
            }
            else {
                return FALSE;
            }
        }

Here are two rows that seem to be inserted back to back:

idLocation | factual_id | dateAdded | dateModified | locationName | latitude | longitude
520 | 5f79360f-330f-4035-ae75-e872ea14cfdd | 2013-04-09 14:36:55 | 2013-04-09 14:36:55 | Quiznos | 40.1802 | -74.0258
521 | 5f79360f-330f-4035-ae75-e872ea14cfdd | 2013-04-09 14:36:55 | 2013-04-09 14:36:55 | Quiznos | 40.1802 | -74.0258

回答1:


Although I don't see your implementation of locationID_for_factualID, I'm pretty sure it's doing something like SELECT idLocation ... WHERE factual_id = '$factual_id' (don't forget to use query params!).

I can imagine you're having a race condition, i.e. two requests callign the same script with the same input data at almost the same time, then calling the function locationID_for_factualID and both finding that $idLocation == false. Then, both requests execute the INSERT and you end up with a duplicate record.

The standard solution for this issue is to use transactions. Have a look here how this is done. The important part is wrapping the SELECT inside of locationID_for_factualID AND the INSERT with the same transaction, i.e. between START TRANSACTION and COMMIT. You'll probably have to change the implementation of locationID_for_factualID to use the same DB connection as the following INSERT.

As an aside, you might want to create a UNIQUE INDEX on column factual_id. This will prevent the same factual_id from occurring more than once by letting the INSERT statement fail if it tries to insert a duplicate.



来源:https://stackoverflow.com/questions/15905188/mysql-rows-inserted-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!