SQL Server Вставьте запрос на форум
-
08-10-2019 - |
Вопрос
Учитывая таблицу форума и многие пользователи одновременно вставляют в нее сообщения, насколько безопасна эта транзакция?
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @LastMessageId SMALLINT
SELECT @LastMessageId = MAX(MessageId)
FROM Discussions
WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId
INSERT INTO Discussions
(ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
VALUES
(@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)
IF @@ERROR = 0
BEGIN
COMMIT TRANSACTION
RETURN 0
END
ROLLBACK TRANSACTION
RETURN 1
Здесь я прочитал последнее сообщение и увеличиваю его. Я не могу использовать поле идентификации, потому что он должен быть увеличен для каждого сообщения, вставленного в группу (не каждое сообщение вставляется в таблицу.)
Решение
Ваша транзакция должна быть действительно вполне безопасна - проверьте MSDN Docs на уровне сериализации транзакции:
Сериализация
Указывает следующее:
Заявления не может прочитать данные, которые были изменены но еще не совершается другими транзакциями.
Другие транзакции не могут изменять данные Это было прочитано текущей транзакцией до завершения текущей транзакции.
Другие транзакции не могут вставлять новые строки с ключевыми значениями, которые попадут в диапазон клавиш, прочитанные любыми утверждениями в текущей транзакции, пока текущая транзакция не завершится.
Плоки диапазона размещены в диапазоне значений ключей, которые соответствуют условиям поиска каждого оператора, выполняемого в транзакции. Это блокирует другие транзакции от обновления или вставки любых строк, которые будут претендовать на любую из операторов, выполненных текущей транзакцией. Это означает, что если какое-либо из заявлений в транзакции выполняется во второй раз, они будут читать тот же набор строк. Плоки диапазона удерживаются до завершения транзакции. Это самый ограничивающий уровень изоляции, потому что он блокирует целые диапазоны клавиш и удерживает замки до завершения транзакции. Поскольку параллелизм ниже, используйте эту опцию только при необходимости. Эта опция имеет тот же эффект, что и настройка HOLDLOLOL на всех таблицах во всех операторах выбора в транзакции.
Основная проблема с этим уровнем изоляции транзакции состоит в том, что это довольно тяжелая нагрузка на сервере, и сериализуется (в качестве имени подразумевает) любой доступ, поэтому производительность и масштабируемость вашего сервера пострадают, например, с очень большим количеством пользователей, вы Возможно получить много тайм-аутов для пользователей, ожидающих транзакции для завершения.
Так что используя более легкий подход глобального идентификатора сообщения как INT IDENTITY
Определенно намного лучше!