Вопрос про транзации и deadlocks
От: Divineshadow  
Дата: 08.07.15 13:57
Оценка:
Здравствуйте.
Есть таблица с двумя полями: 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, то коммита не будет
            }
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.