Download & Extend

Cannot drupal_write_record() on table after it is locked with db_lock_table()

Project:Drupal core
Version:6.x-dev
Component:database system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

If you try to call drupal_write_record('some_table', ...) after acquiring a lock on that table using db_lock_table('some_table'), you will get tons of errors having to do with locks on other tables. Here's an excerpt:

user warning: Table 'cache' was not locked with LOCK TABLES query: SELECT data, created, headers, expire, serialized FROM cache WHERE cid = 'schema' in /home/threexk/public_html/sandbox_d6_cvs/includes/cache.inc on line 26.

Test code that causes error:
<?php
db_lock_table
('schematest');
$record = new StdClass();
$record->field1 = 'abc';
$record->field2 = 123;
drupal_write_record('schematest', $record);
db_unlock_tables();
?>

Attached is (1) the module used to generate the test case, and (2) a copy/paste of all errors.

MySQL: 5.0.67
PHP memory limit: 5.2.6

In case it's relevant, my MySQL max_allowed_packet=16M and my PHP memory limit is 512MB. I tried upping the max_allowed_packet based on discussions of other issues, but that had no effect.

AttachmentSizeStatusTest resultOperations
schematest.tgz475 bytesIgnored: Check issue status.NoneNone
errors.txt79.63 KBIgnored: Check issue status.NoneNone

Comments

#1

Here are the grants for the database user (as given by "show grants"):
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON `sandbox_d6_cvs`.* TO 'sandbox'@'localhost'

#2

I ran into the same issue. See #675952: "Tables not locked" error when creating rule

Here's the part of the striped code:

<?php
db_lock_table
('themekey_properties');
drupal_write_record('themekey_properties', $item, array());
db_unlock_tables();
?>

The Problem is that drupal_write_record() calls drupal_get_schema() which uses caching. The cache table isn't locked.
But drupal_get_schema() additionally caches the schema in an internal static variable. That's the reason why drupal_write_record() in combination with db_lock_table() doesn't always fail.
By knowing this you can do that workaround:

<?php
drupal_get_schema
(FALSE);
db_lock_table('themekey_properties');
drupal_write_record('themekey_properties', $item, array());
db_unlock_tables();
?>