diff --git a/camel/camel-db.c b/camel/camel-db.c
index 265c56a..b3d3b42 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -41,6 +41,12 @@
 /* how long to wait before invoking sync on the file */
 #define SYNC_TIMEOUT_SECONDS 5
 
+#define READER_LOCK(cdb) g_static_rw_lock_reader_lock (&cdb->priv->rwlock)
+#define READER_UNLOCK(cdb) g_static_rw_lock_reader_unlock (&cdb->priv->rwlock)
+#define WRITER_LOCK(cdb) g_static_rw_lock_writer_lock (&cdb->priv->rwlock)
+#define WRITER_UNLOCK(cdb) g_static_rw_lock_writer_unlock (&cdb->priv->rwlock)
+
+
 static sqlite3_vfs *old_vfs = NULL;
 
 typedef struct {
@@ -353,14 +359,24 @@ init_sqlite_vfs (void)
 
 struct _CamelDBPrivate {
 	GTimer *timer;
+	GStaticRWLock rwlock;
 	gchar *file_name;
+	gboolean transaction_is_on;
 };
 
-static GStaticRecMutex trans_lock = G_STATIC_REC_MUTEX_INIT;
-
+/**
+ * cdb_sql_exec 
+ * @db: 
+ * @stmt: 
+ * @error: 
+ * 
+ * Callers should hold the lock
+ **/
 static gint
 cdb_sql_exec (sqlite3 *db,
               const gchar *stmt,
+	      gint (*callback)(void*,gint,gchar**,gchar**),
+	      gpointer data,
               GError **error)
 {
 	gchar *errmsg = NULL;
@@ -368,7 +384,7 @@ cdb_sql_exec (sqlite3 *db,
 
 	d(g_print("Camel SQL Exec:\n%s\n", stmt));
 
-	ret = sqlite3_exec(db, stmt, 0, 0, &errmsg);
+	ret = sqlite3_exec (db, stmt, callback, data, &errmsg);
 	while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED || ret == -1) {
 		if (errmsg) {
 			sqlite3_free (errmsg);
@@ -476,9 +492,9 @@ camel_db_open (const gchar *path,
 
 	cdb = g_new (CamelDB, 1);
 	cdb->db = db;
-	cdb->lock = g_mutex_new ();
-	cdb->priv = g_new(CamelDBPrivate, 1);
-	cdb->priv->file_name = g_strdup(path);
+	cdb->priv = g_new (CamelDBPrivate, 1);
+	cdb->priv->file_name = g_strdup (path);
+	g_static_rw_lock_init (&cdb->priv->rwlock);
 	cdb->priv->timer = NULL;
 	d(g_print ("\nDatabase succesfully opened  \n"));
 
@@ -528,7 +544,9 @@ camel_db_close (CamelDB *cdb)
 {
 	if (cdb) {
 		sqlite3_close (cdb->db);
-		g_mutex_free (cdb->lock);
+		g_static_rw_lock_free (&cdb->priv->rwlock);
+		g_free (cdb->priv->file_name);
+		g_free (cdb->priv);
 		g_free (cdb);
 		d(g_print ("\nDatabase succesfully closed \n"));
 	}
@@ -547,11 +565,11 @@ camel_db_set_collate (CamelDB *cdb, const gchar *col, const gchar *collate, Came
 		if (!cdb)
 			return 0;
 
-		g_mutex_lock (cdb->lock);
+		WRITER_LOCK (cdb);
 		d(g_print("Creating Collation %s on %s with %p\n", collate, col, (gpointer) func));
 		if (collate && func)
-			ret = sqlite3_create_collation(cdb->db, collate, SQLITE_UTF8,  NULL, func);
-		g_mutex_unlock (cdb->lock);
+			ret = sqlite3_create_collation (cdb->db, collate, SQLITE_UTF8,  NULL, func);
+		WRITER_UNLOCK (cdb);
 
 		return ret;
 }
@@ -570,12 +588,15 @@ camel_db_command (CamelDB *cdb,
 
 	if (!cdb)
 		return TRUE;
-	g_mutex_lock (cdb->lock);
+	
+	WRITER_LOCK (cdb);
 
-	START(stmt);
-	ret = cdb_sql_exec (cdb->db, stmt, error);
+	START (stmt);
+	ret = cdb_sql_exec (cdb->db, stmt, NULL, NULL, error);
 	END;
-	g_mutex_unlock (cdb->lock);
+	
+	WRITER_UNLOCK (cdb);
+
 
 	return ret;
 }
@@ -591,13 +612,13 @@ camel_db_begin_transaction (CamelDB *cdb,
 {
 	if (!cdb)
 		return -1;
-	if (g_getenv("SQLITE_TRANSLOCK"))
-		g_static_rec_mutex_lock (&trans_lock);
 
-	g_mutex_lock (cdb->lock);
+	WRITER_LOCK (cdb);
 	STARTTS("BEGIN");
 
-	return (cdb_sql_exec (cdb->db, "BEGIN", error));
+	cdb->priv->transaction_is_on = TRUE;
+
+	return (cdb_sql_exec (cdb->db, "BEGIN", NULL, NULL, error));
 }
 
 /**
@@ -613,12 +634,11 @@ camel_db_end_transaction (CamelDB *cdb,
 	if (!cdb)
 		return -1;
 
-	ret = cdb_sql_exec (cdb->db, "COMMIT", error);
+	ret = cdb_sql_exec (cdb->db, "COMMIT", NULL, NULL, error);
+	cdb->priv->transaction_is_on = FALSE;
+	
 	ENDTS;
-	g_mutex_unlock (cdb->lock);
-	if (g_getenv("SQLITE_TRANSLOCK"))
-		g_static_rec_mutex_unlock (&trans_lock);
-
+	WRITER_UNLOCK (cdb);
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 
 	return ret;
@@ -635,10 +655,10 @@ camel_db_abort_transaction (CamelDB *cdb,
 {
 	gint ret;
 
-	ret = cdb_sql_exec (cdb->db, "ROLLBACK", error);
-	g_mutex_unlock (cdb->lock);
-	if (g_getenv("SQLITE_TRANSLOCK"))
-		g_static_rec_mutex_unlock (&trans_lock);
+	ret = cdb_sql_exec (cdb->db, "ROLLBACK", NULL, NULL, error);
+	cdb->priv->transaction_is_on = FALSE;
+
+	WRITER_UNLOCK (cdb);
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 
 	return ret;
@@ -657,7 +677,9 @@ camel_db_add_to_transaction (CamelDB *cdb,
 	if (!cdb)
 		return -1;
 
-	return (cdb_sql_exec (cdb->db, stmt, error));
+	g_assert (cdb->priv->transaction_is_on == TRUE);
+
+	return (cdb_sql_exec (cdb->db, stmt, NULL, NULL, error));
 }
 
 /**
@@ -676,24 +698,25 @@ camel_db_transaction_command (CamelDB *cdb,
 	if (!cdb)
 		return -1;
 
-	g_mutex_lock (cdb->lock);
+	WRITER_LOCK (cdb);
+
 	STARTTS("BEGIN");
-	ret = cdb_sql_exec (cdb->db, "BEGIN", error);
+	ret = cdb_sql_exec (cdb->db, "BEGIN", NULL, NULL, error);
 	if (ret)
 		goto end;
 
 	while (qry_list) {
 		query = qry_list->data;
-		ret = cdb_sql_exec (cdb->db, query, error);
+		ret = cdb_sql_exec (cdb->db, query, NULL, NULL, error);
 		if (ret)
 			goto end;
 		qry_list = g_slist_next (qry_list);
 	}
 
-	ret = cdb_sql_exec (cdb->db, "COMMIT", error);
+	ret = cdb_sql_exec (cdb->db, "COMMIT", NULL, NULL, error);
 	ENDTS;
 end:
-	g_mutex_unlock (cdb->lock);
+	WRITER_UNLOCK (cdb);
 	return ret;
 }
 
@@ -723,41 +746,18 @@ camel_db_count_message_info (CamelDB *cdb,
                              GError **error)
 {
 	gint ret = -1;
-	gchar *errmsg = NULL;
-
-	g_mutex_lock (cdb->lock);
 
-	START(query);
-	ret = sqlite3_exec(cdb->db, query, count_cb, count, &errmsg);
-	while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
-		if (errmsg) {
-			sqlite3_free (errmsg);
-			errmsg = NULL;
-		}
-
-		ret = sqlite3_exec (cdb->db, query, count_cb, count, &errmsg);
-	}
 
+	READER_LOCK (cdb);
+	
+	START (query);
+	ret = cdb_sql_exec (cdb->db, query, count_cb, count, error);
 	END;
 
-	g_mutex_unlock (cdb->lock);
+	READER_UNLOCK (cdb);
 
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 
-	if (ret != SQLITE_OK) {
-		d(g_print ("Error in SQL SELECT statement: %s [%s]\n", query, errmsg));
-		g_set_error (
-			error, CAMEL_ERROR,
-			CAMEL_ERROR_GENERIC, "%s", errmsg);
-		sqlite3_free (errmsg);
-		errmsg = NULL;
-	}
-
-	if (errmsg) {
-		sqlite3_free (errmsg);
-		errmsg = NULL;
-	}
-
 	return ret;
 }
 
@@ -949,46 +949,21 @@ camel_db_select (CamelDB *cdb,
                  gpointer data,
                  GError **error)
 {
-	gchar *errmsg = NULL;
-	/*int nrecs = 0;*/
 	gint ret = -1;
 
 	if (!cdb)
 		return ret;
 
 	d(g_print ("\n%s:\n%s \n", G_STRFUNC, stmt));
-	g_mutex_lock (cdb->lock);
-
-	START(stmt);
-	ret = sqlite3_exec(cdb->db, stmt, callback, data, &errmsg);
-	while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
-		if (errmsg) {
-			sqlite3_free (errmsg);
-			errmsg = NULL;
-		}
-
-		ret = sqlite3_exec (cdb->db, stmt, callback, data, &errmsg);
-	}
+	READER_LOCK (cdb);
 
+	START (stmt);
+	ret = cdb_sql_exec (cdb->db, stmt, callback, data, error);
 	END;
 
-	g_mutex_unlock (cdb->lock);
+	READER_UNLOCK (cdb);
 	CAMEL_DB_RELEASE_SQLITE_MEMORY;
 
-	if (ret != SQLITE_OK) {
-		d(g_warning ("Error in select statement '%s' [%s].\n", stmt, errmsg));
-		g_set_error (
-			error, CAMEL_ERROR,
-			CAMEL_ERROR_GENERIC, "%s", errmsg);
-		sqlite3_free (errmsg);
-		errmsg = NULL;
-	}
-
-	if (errmsg) {
-		sqlite3_free (errmsg);
-		errmsg = NULL;
-	}
-
 	return ret;
 }
 
@@ -1618,25 +1593,26 @@ camel_db_write_folder_version (CamelDB *cdb,
 }
 
 static gint
+read_version_callback (gpointer ref, gint ncol, gchar ** cols, gchar ** name)
+{
+	gint *version = (gint *) ref;
+
+	if (cols [0])
+		*version = strtoul (cols [0], NULL, 10);
+
+	return 0;
+}
+
+static gint
 camel_db_get_folder_version (CamelDB *cdb,
                              const gchar *folder_name,
                              GError **error)
 {
 	gint version = -1, ret;
 	gchar *query;
-	sqlite3_stmt *stmt = NULL;
 
 	query = sqlite3_mprintf ("SELECT version FROM '%q_version'", folder_name);
-
-	ret = sqlite3_prepare_v2 (cdb->db, query, -1, &stmt, NULL);
-
-	if (ret == SQLITE_OK)
-		ret = sqlite3_step (stmt);
-	if (ret == SQLITE_ROW || ret == SQLITE_OK)
-		version = sqlite3_column_int (stmt, 0);
-
-	sqlite3_finalize (stmt);
-
+	ret = camel_db_select (cdb, query, read_version_callback, &version, error);
 	sqlite3_free (query);
 
 	return version;
@@ -1653,21 +1629,44 @@ camel_db_prepare_message_info_table (CamelDB *cdb,
                                      GError **error)
 {
 	gint ret, current_version;
+	GError *err = NULL;
 
 	/* Make sure we have the table already */
-	ret = camel_db_create_message_info_table (cdb, folder_name, error);
+	camel_db_begin_transaction (cdb, &err);
+	ret = camel_db_create_message_info_table (cdb, folder_name, &err);
+	if (err)
+		goto exit;
+
+	camel_db_end_transaction (cdb, &err);
 
 	/* Migration stage zero: version fetch */
-	current_version = camel_db_get_folder_version (cdb, folder_name, error);
+	current_version = camel_db_get_folder_version (cdb, folder_name, &err);
 
+	camel_db_begin_transaction (cdb, &err);
+	
 	/* Migration stage one: storing the old data if necessary */
-	ret = camel_db_migrate_folder_prepare (cdb, folder_name, current_version, error);
+	ret = camel_db_migrate_folder_prepare (cdb, folder_name, current_version, &err);
+	if (err)
+		goto exit;
 
 	/* Migration stage two: rewriting the old data if necessary */
-	ret = camel_db_migrate_folder_recreate (cdb, folder_name, current_version, error);
+	ret = camel_db_migrate_folder_recreate (cdb, folder_name, current_version, &err);
+	if (err)
+		goto exit;
 
 	/* Final step: (over)write the current version label */
-	ret = camel_db_write_folder_version (cdb, folder_name, current_version, error);
+	ret = camel_db_write_folder_version (cdb, folder_name, current_version, &err);
+	if (err)
+		goto exit;
+	
+	camel_db_end_transaction (cdb, &err);
+
+exit:
+	if (err && cdb->priv->transaction_is_on)
+		camel_db_abort_transaction (cdb, NULL);
+	
+	if (err)
+		g_propagate_error (error, err);
 
 	return ret;
 }
diff --git a/camel/camel-db.h b/camel/camel-db.h
index 3dcd06e..744a2e8 100644
--- a/camel/camel-db.h
+++ b/camel/camel-db.h
@@ -56,6 +56,8 @@ typedef gint(*CamelDBCollate)(gpointer ,int,gconstpointer ,int,gconstpointer );
  **/
 struct _CamelDB {
 	sqlite3 *db;
+	/* this lock has been replaced with a rw lock which sits inside priv. 
+	   This is currently unused. Keeping it, not to break the ABI */
 	GMutex *lock;
 	CamelDBPrivate *priv;
 };
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 5667e11..f0ac7d6 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -2194,11 +2194,15 @@ save_message_infos_to_db (CamelFolderSummary *s,
 		return -1;
 
 	camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+	
 	/* Push MessageInfo-es */
+	camel_db_begin_transaction (cdb, NULL);
 	g_hash_table_foreach (s->loaded_infos, save_to_db_cb, &args);
+	camel_db_end_transaction (cdb, NULL);
+	
 	camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-/* FIXME[disk-summary] make sure we free the message infos that are loaded
- * are freed if not used anymore or should we leave that to the timer? */
+	/* FIXME[disk-summary] make sure we free the message infos that are loaded
+	 * are freed if not used anymore or should we leave that to the timer? */
 
 	return 0;
 }
@@ -2235,12 +2239,14 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
 
 	d(printf ("\ncamel_folder_summary_save_to_db called \n"));
 	if (CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s)->need_preview && g_hash_table_size(CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s)->preview_updates)) {
-		camel_db_begin_transaction (parent_store->cdb_w, NULL);
 		camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+		
+		camel_db_begin_transaction (parent_store->cdb_w, NULL);
 		g_hash_table_foreach (CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s)->preview_updates, (GHFunc)msg_save_preview, s->folder);
 		g_hash_table_remove_all (CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s)->preview_updates);
-		camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 		camel_db_end_transaction (parent_store->cdb_w, NULL);
+		
+		camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 	}
 
 	if (!(s->flags & CAMEL_SUMMARY_DIRTY))
@@ -2252,11 +2258,8 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
 	if (!count)
 		return camel_folder_summary_header_save_to_db (s, error);
 
-	camel_db_begin_transaction (cdb, NULL);
-
 	ret = save_message_infos_to_db (s, FALSE, error);
 	if (ret != 0) {
-		camel_db_abort_transaction (cdb, NULL);
 		/* Failed, so lets reset the flag */
 		s->flags |= CAMEL_SUMMARY_DIRTY;
 		return -1;
@@ -2268,25 +2271,21 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
 		strstr ((*error)->message, "26 columns but 28 values") != NULL) {
 		const gchar *full_name;
 
-		/* This is an error is previous migration. Let remigrate this folder alone. */
-		camel_db_abort_transaction (cdb, NULL);
 		full_name = camel_folder_get_full_name (s->folder);
-		camel_db_reset_folder_version (cdb, full_name, 0, NULL);
 		g_warning ("Fixing up a broken summary migration on %s\n", full_name);
+		
 		/* Begin everything again. */
 		camel_db_begin_transaction (cdb, NULL);
+		camel_db_reset_folder_version (cdb, full_name, 0, NULL);
+		camel_db_end_transaction (cdb, NULL);
 
 		ret = save_message_infos_to_db (s, FALSE, error);
 		if (ret != 0) {
-			camel_db_abort_transaction (cdb, NULL);
-			/* Failed, so lets reset the flag */
 			s->flags |= CAMEL_SUMMARY_DIRTY;
 			return -1;
 		}
 	}
 
-	camel_db_end_transaction (cdb, NULL);
-
 	record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
 	if (!record) {
 		s->flags |= CAMEL_SUMMARY_DIRTY;
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 991a8ff..92090d4 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -352,7 +352,6 @@ gint camel_folder_summary_save_to_db (CamelFolderSummary *s, GError **error);
 gint camel_folder_summary_load_from_db (CamelFolderSummary *s, GError **error);
 
 /* only load the header */
-gint camel_folder_summary_header_load(CamelFolderSummary *summary);
 gint camel_folder_summary_header_load_from_db (CamelFolderSummary *s, struct _CamelStore *store, const gchar *folder_name, GError **error);
 gint camel_folder_summary_header_save_to_db (CamelFolderSummary *s, GError **error);
 
diff --git a/camel/camel-store.c b/camel/camel-store.c
index e30fa1d..72594de 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -113,10 +113,6 @@ store_finalize (GObject *object)
 	if (store->cdb_r != NULL) {
 		camel_db_close (store->cdb_r);
 		store->cdb_r = NULL;
-	}
-
-	if (store->cdb_w != NULL) {
-		camel_db_close (store->cdb_w);
 		store->cdb_w = NULL;
 	}
 
@@ -203,8 +199,8 @@ store_construct (CamelService *service,
 		return FALSE;
 	}
 
-	/* This is for writing to the store */
-	store->cdb_w = camel_db_clone (store->cdb_r, error);
+	/* keep cb_w to not break the ABI */
+	store->cdb_w = store->cdb_r;
 
 	if (camel_url_get_param(url, "filter"))
 		store->flags |= CAMEL_STORE_FILTER_INBOX;
