Does Drupal cache db_query results for multiple users? I am running into something strange and perhaps someone here can help me. I am trying to prevent two things from happening at once because the second attempt might be influenced by the first attempt.

The (simplified) code:

function save_my_thing($thing) {
  module_invoke_all('my_thing_presave');
    &gt;&gt;&gt; INVOCATION

      if (!lock_acquire('mything_lock')) {
        // If  we cannot obtain a lock, wait.
        lock_wait('mything_lock');
      }

      $sql = "SELECT COUNT(*) FROM {my_things}";
      $count = db_query($sql, array())-&gt;fetchField();

      if($count &gt;= 1) {
        drupal_set_message('already there','error');
        drupal_goto(drupal_get_destination());
      }

    &gt;&gt;&gt; END INVOCATION

  drupal_write_record('my_things', $thing, array('tid'));
  dpm(db_query('SELECT * FROM {my_things} WHERE `tid` = ' . $thing-&gt;tid)-&gt;fetchAssoc());

  module_invoke_all('my_thing_save');
    &gt;&gt;&gt; INVOCATION

      lock_release('mything_lock');

    &gt;&gt;&gt; END INVOCATION

}


Above code works perfect if I request the function, wait for it to complete and then call it again. I end up on the page I came from with a visible error.

However if I call this function from two different windows before either of them is finished (as can occur in real life), the sql count returns 0 in both cases. The lock works, and using microtime() I can see the second call starts right after the first call releases the lock. The dpm() returns the inserted row, so the record is written before the lock is released. But SELECT COUNT(*) FROM {my_things} keeps returning 0.

The only thing I can think of now is some kind of fancy SQL caching layer that presents '0' to the second call for some reason, however I could find no such thing in the Drupal database code.

One more interesting thing is that when I move my lock from the custom invoking module to the main module, right before _presave and right after _save. It does work as expected. But then why doesn't this implementation work?
You need to put in an else {...} after using lock_acquire(); or have it return right after calling  lock_wait().

Also, db_query is not cached in any way