Здравствуйте.
Есть таблица с двумя полями: id — автоинкремент, и поле value1 — ну например строковое значение.
Если запустить функцию в нескольких потоках, которая добавляет запись и возвращает новый id, то довольно часто генерируется исключение:
"Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction"
А если попытаться в management studio сделать select всей таблицы, то это исключение генерируется гарантировано
Используемый IsolationLevel = Serializable — и понятно, что когда таблица занята транзакцией из одного потока, то другой не может к ней обратиться.
Вернее он ждёт её освобождения. По крайнее мере я так понимаю принцип работы транзакций с уровнем Serializable.
Объясните пожалуйста, почему возникает исключение и что я не так не так понимаю?
Вот псевдокод функции:
private static int ProcessTableRecord(DbObject dbObject)
{
Connection connection = BeginTransaction(ConnectionString, Connection.IsolationLevel.Serializable);
try
{
var table = connection.Select(string.Format("SELECT * FROM Table1 WHERE value1 = '{0}'", dbObject.Value1));
if (table.Rows.Count > 0)
return Convert.ToInt32(table.Rows[0]["id"]);
int id = connection.InsertIdentity("Table1", dbObject);
return id ;
}
catch
{
connection.RollbackTransaction();
return -1;
}
finally
{
connection.CommitTransaction(); //если был rollback, то коммита не будет
}
}