=== modified file 'includes/database.inc'
--- includes/database.inc	2007-08-30 19:54:21 +0000
+++ includes/database.inc	2007-09-02 14:12:36 +0000
@@ -428,6 +428,26 @@ function db_create_table(&$ret, $name, $
 }
 
 /**
+ * Creates a unique named table with the same structure as an existing table.
+ *
+ * @param $module
+ *   The name of the module that defines the existing table.
+ * @param $table
+ *   The name  of the table to copy. Prefixing is handled by this function,
+ *   so just use the table name.
+ * @return
+ *   Name of the freshly created table.
+ */
+function db_create_table_like($module, $table) {
+  $new_table_name = uniqid('temp_', FALSE);
+  $schema[$new_table_name] = drupal_get_schema_unprocessed($module, $table);
+  _drupal_initialize_schema($module, $schema);
+  $ret = array();
+  db_create_table($ret, $new_table_name, $schema[$new_table_name]);
+  return $new_table_name;
+}
+
+/**
  * Return an array of field names from an array of key/index column
  * specifiers.  This is usually an identity function but if a
  * key/index uses a column prefix specification, this function

=== modified file 'includes/database.mysql-common.inc'
--- includes/database.mysql-common.inc	2007-08-26 08:27:08 +0000
+++ includes/database.mysql-common.inc	2007-09-02 14:15:38 +0000
@@ -481,5 +481,26 @@ function db_last_insert_id($table, $fiel
 }
 
 /**
+ * Renames a table to another, replacing the latter.
+ *
+ * This function uses db specific ways to guarantee that no data loss can
+ * occur. In case of a failure, the replace simply does not happen.
+ *
+ * @param $src
+ *  Name of the source table, usally from db_create_table_like().
+ * @param $target
+ *  Name of the target table.
+ */
+function db_replace_table($src, $target) {
+  if (!db_error()) {
+    $swap_table = uniqid('temp_', FALSE);
+    db_query('RENAME TABLE {'. $target .'} TO '. $swap_table .', {'. $src .'} TO {'. $target .'}');
+    if (!db_error()) {
+      db_query("DROP TABLE $swap_table");
+    }
+  }
+}
+
+/**
  * @} End of "ingroup schemaapi".
- */
\ No newline at end of file
+ */

=== modified file 'includes/database.pgsql.inc'
--- includes/database.pgsql.inc	2007-08-29 18:38:55 +0000
+++ includes/database.pgsql.inc	2007-09-02 14:16:05 +0000
@@ -443,6 +443,26 @@ function db_distinct_field($table, $fiel
 }
 
 /**
+ * Renames a table to an existing one.
+ *
+ * This function uses db specific ways to guarantee that no data loss can
+ * occur. In case of a failure, the rename simply does not happen.
+ *
+ * @param $new_table_name
+ *  Name of the source table, usally from db_create_table_like().
+ * @param $table
+ *  Name of the target table.
+ */
+function db_replace_table($src, $target) {
+  if (!db_error()) {
+    db_query('BEGIN');
+    db_query('DROP TABLE {'. $target .'}');
+    db_query('ALTER TABLE {'. $src .'} RENAME TO {'. $target .'}');
+    db_query('COMMIT');
+  }
+}
+
+/**
  * @} End of "ingroup database".
  */
 

=== modified file 'modules/block/block.module'
--- modules/block/block.module	2007-09-01 05:31:09 +0000
+++ modules/block/block.module	2007-09-02 12:39:13 +0000
@@ -256,19 +256,17 @@ function _block_rehash() {
     }
   }
 
-  db_lock_table('blocks');
-  // Remove all blocks from table.
-  db_query("DELETE FROM {blocks} WHERE theme = '%s'", $theme_key);
 
-  // Reinsert new set of blocks into table.
+  // Reinsert new set of blocks into a temporary table.
+  $temporary_table_name = db_create_table_like('block', 'blocks');
   foreach ($blocks as $block) {
     $block += array(
       'visibility' => NULL,
       'throttle' => NULL,
     );
-    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s', %d)", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title'], $block['cache']);
+    db_query("INSERT INTO $temporary_table_name (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s', %d)", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title'], $block['cache']);
   }
-  db_unlock_tables();
+  db_replace_table($temporary_table_name, 'blocks');
 
   return $blocks;
 }

