Bug Report #1220

Database caching breaks when using two databases with the same prefix

Added by Chris Bandy almost 3 years ago. Updated over 2 years ago.

Status:Closed Start date:
Priority:High Due date:
Assignee:Jeremy Bush % Done:

100%

Category:Libraries:Database
Target version:2.3.3
Resolution:fixed Points:

Description

In the below test case, queries are being cached across databases and invalid results are returned. The sleep calls are to identify when caching is and is not taking place.

// Server and credentials
$connection = array(
  'type' => 'mysql',
  'host' => 'localhost',
  'socket' => TRUE,
  'user' => 'root',
  'pass' => 'password',
);

$db1 = Database::instance('first', array(
  'cache' => TRUE,
  'connection' => array_merge($connection, array('database' => 'testfirst')),
));

$db2 = Database::instance('second', array(
  'cache' => TRUE,
  'connection' => array_merge($connection, array('database' => 'testsecond')),
));

$db1->query('CREATE TABLE testtable ( firstfield integer )');
$db1->query('INSERT INTO testtable VALUES ( 1 )');
$db1->query('INSERT INTO testtable VALUES ( 2 )');

// CREATE statement is cached
$db1->clear_cache();

$db2->query('CREATE TABLE testtable ( firstfield integer )');
$db2->query('INSERT INTO testtable VALUES ( 5 )');

// Clear all caches
$db1->clear_cache();
$db2->clear_cache();

// These queries should return different results
$result1 = $db1->query('SELECT *, SLEEP(0.5) FROM testtable')->as_array(); // 1
$result2 = $db2->query('SELECT *, SLEEP(0.5) FROM testtable')->as_array(); // 2

$db2->clear_cache();

// Correct results are obtained after clearing the cache
$result3 = $db2->query('SELECT *, SLEEP(0.5) FROM testtable')->as_array(); // 3

// These queries should still be cached
$db1->query('SELECT *, SLEEP(0.5) FROM testtable')->as_array(); // 4
$db2->query('SELECT *, SLEEP(0.5) FROM testtable')->as_array(); // 5

$db1->query('DROP TABLE testtable');

// DROP statement is cached
$db1->clear_cache();

$db2->query('DROP TABLE testtable');
Current Results:
  • Queries 1 and 3 are not cached.
  • Queries 2, 4, and 5 are cached.
  • Results 1 and 2 match.
  • Results 2 and 3 differ.
Expected Results:
  • Queries 1, 2, and 3 should not be cached.
  • Queries 4 and 5 should be cached.
  • Results 1 and 2 should differ.
  • Results 2 and 3 should match.

Solution:

Query caching should happen per DB config group.

0001-Instance-member-rather-than-class-attribute.patch - One possible solution (against trunk) (4.9 kB) Chris Bandy, 03/29/2009 09:15 pm


Related issues

related to Kohana v2.x - Bug Report #1049: Database::list_fields returns incorrect results for multi... 2.3.3 Closed

Associated revisions

Revision 4343
Added by John Heathco over 2 years ago

fixing #1220 - thanks chris

History

Updated by Bob - almost 3 years ago

I think a more elegant solution would be to push the config group name to the drivers and then append the name to the SQL statement before hashing the query.

Updated by Chris Bandy almost 3 years ago

Using a key to partition a class member for each inherited instance is not correct, IMO.

Each instance of Database_Driver manages a single connection to a database, and queries should be cached per connection (i.e., not cached across connections.)

$db1 = new Database_Driver($config1);
$db2 = new Database_Driver($config2);

These two objects should not share a query cache.

Updated by John Heathco over 2 years ago

  • Resolution set to fixed

Updated by John Heathco over 2 years ago

  • Status changed from New to Closed
  • % Done changed from 0 to 100

Applied in changeset r4343.

Also available in: Atom PDF