/**
* Start a transaction.
*
+ * A serializable transaction forces a strict separation between other
+ * transactions. Due to the performance overhead they should only be used
+ * in certain situations (e.g. SELECT->INSERT|UPDATE).
+ *
* @note Either commit() or rollback() has to be called to end the
* transaction.
* @note Transactions are thread-specific. So commit()/rollbak() has to be
* not supported. So if any if the "inner" transactions are rolled back
* the outer most transaction is rolled back.
*
- * @return TRUE on success
+ * @param serializable TRUE to create a serializable transaction
+ * @return TRUE on success
*/
- bool (*transaction)(database_t *this);
+ bool (*transaction)(database_t *this, bool serializable);
/**
* Commit all changes made during the current transaction.
}
METHOD(database_t, transaction, bool,
- private_mysql_database_t *this)
+ private_mysql_database_t *this, bool serializable)
{
transaction_t *trans = NULL;
conn_t *conn;
}
/* these statements are not supported in prepared statements that are used
* by the execute() method */
+ if (serializable)
+ {
+ if (mysql_query(conn->mysql,
+ "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE") != 0)
+ {
+ DBG1(DBG_LIB, "starting transaction failed: %s",
+ mysql_error(conn->mysql));
+ conn_release(this, conn);
+ return FALSE;
+ }
+ }
if (mysql_query(conn->mysql, "START TRANSACTION") != 0)
{
DBG1(DBG_LIB, "starting transaction failed: %s",
}
METHOD(database_t, transaction, bool,
- private_sqlite_database_t *this)
+ private_sqlite_database_t *this, bool serializable)
{
transaction_t *trans;
+ char *cmd = serializable ? "BEGIN EXCLUSIVE TRANSACTION"
+ : "BEGIN TRANSACTION";
trans = this->transaction->get(this->transaction);
if (trans)
ref_get(&trans->refs);
return TRUE;
}
- if (execute(this, NULL, "BEGIN EXCLUSIVE TRANSACTION") == -1)
+ if (execute(this, NULL, cmd) == -1)
{
return FALSE;
}
id = create_pool(name, start_addr, end_addr, timeout);
printf("allocating %d addresses... ", count);
fflush(stdout);
- db->transaction(db);
+ db->transaction(db, FALSE);
while (TRUE)
{
db->execute(db, NULL,
host_t *addr;
FILE *file;
- db->transaction(db);
+ db->transaction(db, FALSE);
addr = host_create_from_string("%any", 0);
pool_id = create_pool(pool, addr->get_address(addr),
}
DESTROY_IF(old_end);
- db->transaction(db);
+ db->transaction(db, FALSE);
if (db->execute(db, NULL,
"UPDATE pools SET end = ? WHERE name = ?",
DB_BLOB, new_addr, DB_TEXT, name) <= 0)
exit(EXIT_FAILURE);
}
- db->transaction(db);
+ db->transaction(db, FALSE);
while (fgets(command, sizeof(command), file))
{
char *argv[ARGV_SIZE], *start;