Подтвердить что ты не робот

Являются ли временные таблицы потокобезопасными?

Я использую SQL Server 2000, и многие из хранимых процедур широко используют временные таблицы. В базе данных много трафика, и я беспокоюсь о безопасности потоков при создании и удалении временных таблиц.

Предположим, что у меня есть хранимая процедура, которая создает несколько временных таблиц, она может даже присоединяться к временным таблицам к другим временным таблицам и т.д. И позволяет также сказать, что два пользователя одновременно выполняют хранимую процедуру.

  • Возможно ли, чтобы один пользователь запускал sp и создает временную таблицу с именем #temp, а другой пользователь запускает тот же sp, но останавливается, потому что таблица с именем #temp уже существует в базе данных?

  • Как насчет того, если один и тот же пользователь дважды выполняет одну и ту же хранимую процедуру в одном соединении?

  • Существуют ли какие-либо другие странные сценарии, которые могут вызвать взаимные запросы двух пользователей?

4b9b3361

Ответ 1

В первом случае нет, это невозможно, потому что #temp является локальной временной таблицей и поэтому не видима для других подключений (предполагалось, что ваши пользователи используют отдельные подключения к базе данных). Имя временной таблицы псевдониму присваивается произвольному имени, которое создается, и вы ссылаетесь на это, когда ссылаетесь на свою локальную таблицу темп.

В вашем случае, поскольку вы создаете локальную таблицу temp в хранимой процедуре, что временная таблица будет удалена при выходе из процедуры процедуры (см. раздел "Замечания" ).

Для второго случая, да, вы получите эту ошибку, потому что таблица уже существует, и таблица длится столько же времени, сколько это делает соединение. Если это так, то я рекомендую вам проверить наличие таблицы, прежде чем пытаться ее создать.

Ответ 2

Локальные временные таблицы (с одним #) создаются с идентификатором в конце их, что делает их уникальными; несколько вызывающих абонентов (даже с тем же именем) никогда не должны перекрываться.

(Попробуйте: создайте одну и ту же временную таблицу из двух подключений и того же имени. Затем запросите tempdb.dbo.sysobjects, чтобы увидеть созданные фактические таблицы...)

Ответ 3

Локальные временные таблицы являются потокобезопасными, потому что они существуют только в текущем контексте. Не путайте контекст с текущим подключением (от MSDN: "Местная временная таблица, созданная в хранимой процедуре, автоматически отбрасывается, когда сохраненная процедура завершена" ), то же соединение может безопасно вызывать два или более раз хранимую процедуру, которая создает локальную таблицу темпа (например, #TMP).

Вы можете проверить это поведение, выполнив следующую хранимую процедуру из двух соединений. Этот SP будет ждать 30 секунд, поэтому мы можем быть уверены, что два потока будут работать над их собственными версиями таблицы #TMP в одно и то же время:

CREATE PROCEDURE myProc(@n INT)
AS BEGIN
    RAISERROR('running with (%d)', 0, 1, @n);
    CREATE TABLE #TMP(n INT);
    INSERT #TMP VALUES(@n);
    INSERT #TMP VALUES(@n * 10);
    INSERT #TMP VALUES(@n * 100);
    WAITFOR DELAY '00:00:30';
    SELECT * FROM #TMP;
END;

Ответ 4

Таблицы Temp привязаны к сеансу, поэтому, если разные пользователи одновременно запускают вашу процедуру, конфликт не возникает...

Ответ 5

Короткий ответ:

Изоляция временных таблиц гарантируется для каждого запроса, и есть ни о чем не беспокоиться ни о потоке, ни о замках, ни о одновременный доступ.

Я не уверен, почему ответы здесь говорят о значении "соединений" и потоков, поскольку это концепции программирования, тогда как изоляция запросов обрабатывается на уровне базы данных.

Локальные временные объекты разделяются сеансом на SQL-сервере. Если у вас есть два запроса, выполняемые одновременно, то они представляют собой два полностью отдельных сеанса и не будут взаимодействовать друг с другом. Вход в систему не имеет значения, например, если вы используете одну строку соединения с использованием ADO.NET(это означает, что несколько параллельных запросов будут использовать один и тот же SQL-запрос "login" ), ваши запросы все равно будут выполняться в отдельных сеансах. Пул соединений также не имеет значения. Локальные временные объекты (таблицы и хранимые процедуры) полностью безопасны для просмотра другими сеансами.

Чтобы прояснить, как это работает; в то время как ваш код имеет одно общее имя для локальных временных объектов, SQL Server добавляет уникальную строку для каждого объекта на каждый сеанс, чтобы сохранить их отдельно. Вы можете увидеть это, выполнив следующее в SSMS:

CREATE TABLE #T (Col1 INT)

SELECT * FROM tempdb.sys.tables WHERE [name] LIKE N'#T%';

Вы увидите для имени следующее:

Т _______________ 00000000001F

Затем, не закрывая эту вкладку запросов, откройте новую вкладку запроса и вставьте этот же запрос и запустите его снова. Теперь вы должны увидеть что-то вроде следующего:

Т _______________ 00000000001F

T _______________ 000000000020

Итак, каждый раз, когда ваш код ссылается на #T, SQL Server переводит его в соответствующее имя на основе сеанса. Разделение осуществляется автоматически, магически.

Ответ 6

Таблицы Temp создаются только в контексте запроса или proc, который их создает. Каждый новый запрос получает контекст в базе данных, который не содержит временных temp-таблиц запросов. Таким образом, столкновение имен не является проблемой.

Ответ 7

Если вы посмотрите в базе данных temps, вы можете увидеть временные таблицы там, и у них есть сгенерированные системой имена. Так что, кроме обычных тупиков, вы должны быть в порядке.

Ответ 8

если вы не используете два знака фунта ## temp, таблица temp будет локальной и существует только для этого локального подключения к пользователю

Ответ 9

Сначала убедитесь, что вы используете реальные временные таблицы, начинаете ли они С# или ##? Если вы создаете фактические таблицы "на лету", а затем повторно отбрасываете их и повторно их создаете, у вас действительно будут проблемы с одновременными пользователями. Если вы создаете глобальные временные таблицы (те, которые начинаются С##), вы также можете иметь проблемы. Если вы не хотите, чтобы проблемы concurrency использовали локальные таблицы temp (они начинаются С#). Кроме того, хорошая практика заключается в том, чтобы явно закрыть их в конце proc (или когда они больше не нужны proc, если вы говорите о длинных многошаговых процедурах) и проверить существование (и, если это так), перед созданием,