DISCLAIMER : Not a Codeigniter Person, Just a MySQL DBA
Looking at the flow of control in the PHP. It says to me:
- Check the following
mod_id
,course_id
,user_id
,interaction_id
- If not found,
INSERT
the new row
- If found,
UPDATE
all the other columns
There are three(3) mechanisms provided for INSERT and UPDATE scenarios
REPLACE INTO `scorm_interactions` SET
`mod_id` = '4',
`course_id` = '5',
`user_id` = '185',
`interaction_id` = 'Question2_1',
`interaction_type` = 'choice',
`time` = '10:45:31',
`weighting` = '1',
`correct_response` = 'Knees*',
`learner_response` = 'Knees*',
`result` = 'correct',
`latency` = '0000:00:02.11',
`objectives` = 'Question2_1',
`description` = ''
;
or
REPLACE INTO `scorm_interactions`
(`mod_id`,`course_id`,`user_id`,`interaction_id`,
`interaction_type`,`time`,`weighting`,`correct_response`,
`learner_response`,`result`,`latency`,`objectives`,`description`) VALUES
('4','5','185','Question2_1','choice','10:45:31','1','Knees*',
'Knees*','correct','0000:00:02.11','Question2_1','');
This mechanically performs DELETE and INSERT on mod_id
, course_id
, user_id
, interaction_id
INSERT INTO `scorm_interactions`
(`mod_id`,`course_id`,`user_id`,`interaction_id`,
`interaction_type`,`time`,`weighting`,`correct_response`,
`learner_response`,`result`,`latency`,`objectives`,`description`) VALUES
('4','5','185','Question2_1',
'choice','10:45:31','1','Knees*',
'Knees*','correct','0000:00:02.11','Question2_1','')
ON DUPLICATE KEY UPDATE
`interaction_type` = 'choice',
`time` = '10:45:31',
`weighting` = '1',
`correct_response` = 'Knees*',
`learner_response` = 'Knees*',
`result` = 'correct',
`latency` = '0000:00:02.11',
`objectives` = 'Question2_1',
`description` = ''
;
Did you know you can perform an exclusive lock on rows you intend to update with precision?
According the MySQL Documentation, you can run a SELECT
query on the very row and issue a row lock along the way. For example:
SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;
This will lock the entire table and allow an UPDATE of the counter_field column.
In your case, simply run the two queries back-to-back
SELECT * FROM `scorm_interactions`
WHERE `mod_id` = '4',
AND `course_id` = '5',
AND `user_id` = '185',
AND `interaction_id` = 'Question2_1'
FOR UPDATE ;
UPDATE `scorm_interactions` SET
`interaction_type` = 'choice',
`time` = '10:45:31',
`weighting` = '1',
`correct_response` = 'Knees*',
`learner_response` = 'Knees*',
`result` = 'correct',
`latency` = '0000:00:02.11',
`objectives` = 'Question2_1',
`description` = ''
WHERE `mod_id` = '4'
AND `course_id` = '5',
AND `user_id` = '185',
AND `interaction_id` = 'Question2_1'
;
EPILOGUE
As a safety cushion, try increasing innodb_lock_wait_timeout if the traffic is write-heavy. See my StackOverflow post : How to debug Lock wait timeout exceeded?
Give it a Try !!!
Best Answer
Perhaps you should look for all tables that have fulltext indexes
To individually remake all tables that have FULLTEXT indexes
If you are OK with the contents of
RemakeTables.sql
, then execute it:CAVEAT : All indexes are remade as well