Friday, August 27, 2010

Re: model->delete error

I'm sorry about your loss, hope you have a backup at least.

My guess is timing and bad luck. A quick look at the source code
suggests that if two deletes of the same Model record overlap during a
small crucial time period, the WHERE condition generated for the
second delete may come out as 1=1.

Here's an example of a sequence of operations that might lead to this
happening:

request 1: enter Model::delete
request 2: enter Model::delete
request 1: Model::delete: check if record exists -> yes
request 2: Model::delete: check if record exists -> yes
request 1: call $db->delete. Record is deleted. Request ends.
request 2: call $db->delete -> enter DboMysqlBase::delete
request 2: DboMysqlBase::delete: obtain default conditions calling
DboSource::defaultConditions
request 2: DboSource::defaultConditions: check if record exists -> NO.
Return null.
request 2: DboSource::conditions: No conditions found, so assume 1=1.
request 2: Delete all records. Request ends.

I haven't tested if this sequence is possible but it seems plausible.

To avoid problems like this the initial SELECT and the DELETEs should
be executed in a transaction.

On Aug 26, 10:20 pm, lloydhome <david.lloydh...@gmail.com> wrote:
> Hi,
>
> I have v1.3.2 running on a production site that has in a controller:
> (effectively, some non-related code removed)
>
> $results = $this->Pipe->find('all', array('conditions'=>$conditions));
> if(sizeof($results) > 1) {
>         $pipes = sizeof($results);
>         for($i = 0; $i < $pipes - 1; $i++) {
>                 $this->Pipe->id = $results[$i]['Pipe']['p_id'];
>                 $this->Pipe->delete();
>                 unset($results[$i]);
>         }
>
> }
>
> so that all but one matching record remains.
>
> Typically, for months now and even within seconds of the error, the
> SQL generated by this code was:
>         DELETE FROM `pipe` WHERE `pipe`.`p_id` = 12345;
>
> until the one time on yesterday it issued:
>         DELETE FROM `pipe` WHERE 1 = 1;
>
> (There went 360000+ records) I see this in the MySQL binlog but cannot
> tell what value for id was set.  It is my understanding that in no
> reasonable case should this cause this SQL to be generated.
>
> Does anyone have an alternate understanding or insight into what went
> wrong?

Check out the new CakePHP Questions site http://cakeqs.org and help others with their CakePHP related questions.

You received this message because you are subscribed to the Google Groups "CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php?hl=en

No comments: