Integrity Constraint Violation: 1062 Duplicate Entry On Production Server Only

Hello mates,

Hope someone could help me with this.

Overview:

The application works on both local and staging server. The is problem on production server only, so I believe it is not an error on the code, but on server configuration(Mysql probably).

I get the following error message when creating a new record:

[indent]Integrity constraint violation: 1062 Duplicate entry ‘166-es’ for key ‘PRIMARY’[/indent]

I use a couple of models related between them for the I18n. In that example the models are Content and ContentLang . Also there is a Weblang model/table to store the available languages. The primary key on ContentLang is Content.id + Weblang.lang .

The error happens when creating the ContentLang record.

All the calls are wrapped on a transaction.

The code:





 $transaction = Yii::app()->db->beginTransaction();

                try {

                    $model->attributes = $_POST['Content'];

                    $model_lang->attributes = $_POST['ContentLang'];


                    if ($model->save()) {

                        $model_lang->content_id = $model->id;


                        if ($model_lang->save()) {

                            $langs = Weblang::getLanguages();


                            foreach ($langs as $l) {    


                                // The following function executes that SQL : 

                                // "SELECT 1 FROM content_lang WHERE content_id = {$content_id} AND lang='{$lang}'"; 

                                //and returns true or false    

                                $exist = Content::model()->isContentInLang($model_lang->content_id, $l);

                               

                                if ($exist == 0) {

                                    $md_lang = new ContentLang();

                                    $md_lang->content_id = $model_lang->content_id;

                                    $md_lang->lang = $l;

                                    $md_lang->friendlyurl = $model_lang->friendlyurl;

                                    $md_lang->title = $model_lang->title;

                                    $md_lang->save(); 

                                }

                            }

                                        $transaction->commit();

                            $this->redirect(array('update', 'id' => $model->id));

                        }

                    }

                    $transaction->rollBack();

                } catch (Exception $e) { 

                    $transaction->rollBack();

                }




Well, I’d like to understand what’s wrong. If it is a problem on server configuration, so I could tell the server admin where to change. The odd thing is that the code works on other servers.

Any help or suggestion is welcome.

Thank you

Hi

  1. what is the version of mysql, php on your server?

  2. did you have any cache system on it?

  3. comment the

…Yii::app()->db->beginTransaction()

…$transaction->commit();

…$transaction->rollBack();

and try again to see if the problem persists.

Thanks for your reply [member=‘KonApaz’].

The answers to your questions are:

  • MYSQL version 5.1.32

  • PHP version 5.2.9

  1. About which cache system are you talking about ?

All I can tell is that the following Apache modules are loaded:

  • mod_file_cache

  • mod_cache

  • mod_disk_cache

If I comment the lines you’ve told I still get the same error. The difference is that the rollback is not executed. So in the DB I have a Content created and only one ContentLang (I should have one for each language). I had to clean it manually after the test.

Some more information:

I realized that if I change


if ($model_lang->save()) {

for


if ($model_lang->validate()) {

the code will work also on the production server.

It sounds like the first entry is created on $model_lang->save() using as primary key the $model->id + the current language. Let’s says ‘80-es’.

Then inside the foreach loop it tries to create an entry with the same primary key again on $md_lang->save() , wich triggers the error.

But as I told before, the weird thing is that the code worked on local server and testing server.

Also I didn’t told, but the testing server doesn’t have the same settings as the production server.

Ok,

Are you sure that the table hasn’t the same id ‘166-es’ ?

How the id generated? did you have sql-trigger or you have modify the beforeSave method?

could you post the code?

Hello [member=‘KonApaz’] and thank you for your reply.

I am sure the entry ‘166-es’ is not created before executing the transaction.

If you check the code in the first post you will see that:

  • The ModelLang attributes are all set manually, not generated.

  • The line "$exist = Content::model()->isContentInLang($model_lang->content_id, $l);" checks if the ModelLang is already created so that we dont try to create it again

Also I’m sure the Model id is generated using Yii’s default method (CActiveRecord::insert), there was no modification made in the beforeSave method.

When it executes the line “$model_lang->save()” it creates the entry ‘166-es’ . And then inside the foreach loop, it seems that the “$exist” always returns false leading to the execution of the line “$md_lang->save();” that tries to create the same entry again. It makes sense, and that’s why if I replace “$model_lang->save()” by “$model_lang->validate()” it will work.

But as I told you before. I would like to understand why the code works fine in other environments and in this specific one it does not work.

The same logical structure in this piece of code is used in other parts of the application, so it would require a big refactor in order to work in this specific server. Since it is the production environment, and it is live right now, I can’t easily do some more radical tests such as connecting to a different database to make sure it isn’t a Mysql server problem.