attr-sql: Use a serializable transaction when inserting identities

This commit is contained in:
Tobias Brunner 2013-10-10 11:02:16 +02:00
parent b283a6e9ef
commit bd085dd978
1 changed files with 5 additions and 12 deletions

View File

@ -50,9 +50,8 @@ static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
{
enumerator_t *e;
u_int row;
int try = 0;
retry:
this->db->transaction(this->db, TRUE);
/* look for peer identity in the identities table */
e = this->db->query(this->db,
"SELECT id FROM identities WHERE type = ? AND data = ?",
@ -61,26 +60,20 @@ retry:
if (e && e->enumerate(e, &row))
{
e->destroy(e);
this->db->commit(this->db);
return row;
}
DESTROY_IF(e);
if (try > 0)
{
return 0;
}
/* not found, insert new one */
if (this->db->execute(this->db, &row,
"INSERT INTO identities (type, data) VALUES (?, ?)",
DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) == 1)
{
this->db->commit(this->db);
return row;
}
/* the INSERT could fail due to the UNIQUE constraint, if the identity was
* added concurrently by another thread or the pool utility,
* therefore try finding it again. a nicer fix would be to use locking
* on the database, but our API currently not supports that */
try++;
goto retry;
this->db->rollback(this->db);
return 0;
}
/**