Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
SELECT @@VERSION
Microsoft SQL Server 2000 - 8.00.2039 (Intel X86)

Помогите разобраться. 1-й клиент через ХП пишет в базу (подключение по ADOCommand). Перед началом его работы вызывается
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRANSACTION
Во время работы 1-го клиента, 2-й клиент (пока просто QA) производит чтение
SELECT * FROM <table> (NOLOCK)
(NOLOCK) необходим, что бы 2-й клиент не ждал окончания транзакции первого, так как она может быть очень долгой. Но не взирая на "READ COMMITTED" в селекте я получаю выборку записей еще до COMMIT TRANSACTION.

Как заставить SELECT * FROM <table> (NOLOCK) возвращать только то, что было до начала транзакции? Суть в том, что бы получать данные только после того, как будет сделан COMMIT, иначе возвращать только то, что было до начала транзакции.
22 сен 09, 12:33    [7691749]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
zenik
Как заставить SELECT * FROM <table> (NOLOCK) возвращать только то, что было до начала транзакции? Суть в том, что бы получать данные только после того, как будет сделан COMMIT, иначе возвращать только то, что было до начала транзакции.
Перейти на 2005 или 2008 сиквел и применить версионность обработки при read committed, например.
22 сен 09, 12:39    [7691798]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik


Как заставить SELECT * FROM <table> (NOLOCK) возвращать только то, что было до начала транзакции?

Никак. NOLOCK - это хинт для чтения грязных данных
22 сен 09, 12:39    [7691803]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
NOLOCK возвращает "грязные", незакоммиченные данные.
22 сен 09, 12:41    [7691816]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
tpg
zenik
Как заставить SELECT * FROM <table> (NOLOCK) возвращать только то, что было до начала транзакции? Суть в том, что бы получать данные только после того, как будет сделан COMMIT, иначе возвращать только то, что было до начала транзакции.
Перейти на 2005 или 2008 сиквел и применить версионность обработки при read committed, например.
Да... Забыл дополнить - без хинта, естественно.
22 сен 09, 12:45    [7691845]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Понял, спасибо. Зачем тогда написано:
BOL
READ COMMITTED
Указывает, что инструкции не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы.... [дальше мыши сгрызли]
22 сен 09, 12:46    [7691856]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
zenik
Понял, спасибо. Зачем тогда написано:
BOL
READ COMMITTED
Указывает, что инструкции не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы.... [дальше мыши сгрызли]
Потому, что так и есть. Где вы тут про NOLOCK нашли?
22 сен 09, 12:51    [7691911]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Понял, спасибо. Зачем тогда написано:
BOL
READ COMMITTED
Указывает, что инструкции не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы.... [дальше мыши сгрызли]

Ну так вы же указали READ COMMITTED в 1ом коннекте, а не во втором.
А TIL одного коннекта никак не действует на другие коннекты
22 сен 09, 12:53    [7691922]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
Дополню :)

BOL:
"Все операции считывания, выполняемые в рамках транзакции, функционируют в соответствии с правилами уровня изоляции, если только табличная подсказка в предложении FROM инструкции не указывает на другое поведение блокировки или управления версиями строк для таблицы."

--------------------------------------------------------------
Дьявол кроется в деталях.
22 сен 09, 12:57    [7691950]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Что то я тогда не втыкаю. Если без (nolock), то SELECT будет висеть и не вернет ничего до тех пор пока транзакция не завершится. Зачем тогда эти уровни изоляции... Непонятно...
22 сен 09, 12:58    [7691961]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Что то я тогда не втыкаю. Если без (nolock), то SELECT будет висеть и не вернет ничего до тех пор пока транзакция не завершится. Зачем тогда эти уровни изоляции... Непонятно...

Еще раз
SET TRANSACTION ISOLATION LEVEL - это для вашего коннекта, а не для всех остальных
Все остальные сами решают, как им работать с транзакциями
22 сен 09, 13:00    [7691975]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Только что попробовал так:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM dbo.Article (NOLOCK)
Разницы не ощутил...
22 сен 09, 13:02    [7691987]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Только что попробовал так:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM dbo.Article (NOLOCK)
Разницы не ощутил...

Какую разницу вы хотите ощутить ?
22 сен 09, 13:04    [7692002]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
zenik
Только что попробовал так:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM dbo.Article (NOLOCK)
Разницы не ощутил...

ответы не читаем, да? :))
22 сен 09, 13:05    [7692008]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Читаю. Вот и появляются новые вопросы.
Я понял, что (nolock) грязное чтение и плевал он на блокировки. Я теперь понять не могу, практического применения уровней изоляции. Или мне еще рано это знать?
22 сен 09, 13:08    [7692027]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Читаю. Вот и появляются новые вопросы.
Я понял, что (nolock) грязное чтение и плевал он на блокировки. Я теперь понять не могу, практического применения уровней изоляции. Или мне еще рано это знать?

Практическое применение уровней изоляции зависит от задачи
22 сен 09, 13:10    [7692040]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Glory
zenik
Только что попробовал так:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM dbo.Article (NOLOCK)
Разницы не ощутил...

Какую разницу вы хотите ощутить ?


Glory
SET TRANSACTION ISOLATION LEVEL - это для вашего коннекта, а не для всех остальных
Все остальные сами решают, как им работать с транзакциями


Пробую для второго конекта задать уровень изоляции.
22 сен 09, 13:11    [7692047]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Glory
zenik
Читаю. Вот и появляются новые вопросы.
Я понял, что (nolock) грязное чтение и плевал он на блокировки. Я теперь понять не могу, практического применения уровней изоляции. Или мне еще рано это знать?

Практическое применение уровней изоляции зависит от задачи


Моя задача: клиентом №1 произвести запись данных в таблицу. Клиентом №2 произвести чтение данных. Клиенты работаю независимо друг от друга. Один пишет когда хочет, второй читает когда хочет. Все просто, если бы не одно но: клиент №2 не должен получить данные, которые клиент №1 пишет внутри транзакции. Есть для этого вменяемые (достаточно простые в реализации) способы решения?
22 сен 09, 13:17    [7692092]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Вы можете установить уровень изоляции для ТЕКУЩЕГО КОННЕКТА через set transaction isolation level. При этом если вы в запросах на этом коннекте НЕ БУДЕТЕ специально указывать хинты блокировок, запросы будут использовать тот уровень изоляции, который вы указали для коннекта.

Вы можете указать уровень изоляции В ЗАПРОСЕ. Это ПЕРЕКРОЕТ УРОВЕНЬ ИЗОЛЯЦИИ ДЛЯ КОННЕКТА. Что в и наблюдаете со своим nolock.

Уровень изоляции READ COMMITTED дает чтение ТОЛЬКО ЗАКОММИЧЕННЫХ ДАННЫХ. Если данные в этот момент меняются с другого коннекта и транзакция там не завершена, ЗАПРОС БУДЕТ ЖДАТЬ ЕЕ ЗАВЕРШЕНИЯ.

ЧИТАТЬ ПРО:
- set transaction isolation level snapshot
- READ_COMMITTED_SNAPSHOT
- ALLOW_SNAPSHOT_ISOLATION
22 сен 09, 13:17    [7692097]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Вот это вот:
GreenSunrise
ЧИТАТЬ ПРО:
- set transaction isolation level snapshot
- READ_COMMITTED_SNAPSHOT
- ALLOW_SNAPSHOT_ISOLATION

для реализации "как сделать так, чтобы писатели не мешали читателям", т.е. что вам и надо.
22 сен 09, 13:19    [7692109]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Glory
zenik
Читаю. Вот и появляются новые вопросы.
Я понял, что (nolock) грязное чтение и плевал он на блокировки. Я теперь понять не могу, практического применения уровней изоляции. Или мне еще рано это знать?

Практическое применение уровней изоляции зависит от задачи


Моя задача: клиентом №1 произвести запись данных в таблицу. Клиентом №2 произвести чтение данных. Клиенты работаю независимо друг от друга. Один пишет когда хочет, второй читает когда хочет. Все просто, если бы не одно но: клиент №2 не должен получить данные, которые клиент №1 пишет внутри транзакции. Есть для этого вменяемые (достаточно простые в реализации) способы решения?

И зачем ваш Клиентом №2 собирается читать всю таблицу ?
22 сен 09, 13:21    [7692120]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
baracs
Member

Откуда: Москва
Сообщений: 7198
GreenSunrise
Вот это вот:
GreenSunrise
ЧИТАТЬ ПРО:
- set transaction isolation level snapshot
- READ_COMMITTED_SNAPSHOT
- ALLOW_SNAPSHOT_ISOLATION

для реализации "как сделать так, чтобы писатели не мешали читателям", т.е. что вам и надо.


Вы на версию сервера в начале топика обратили внимание?
22 сен 09, 13:36    [7692241]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
Glory
И зачем ваш Клиентом №2 собирается читать всю таблицу ?

Так она для него и пишется :) Как же не прочитать...

Для примера запрос клиента 1:
ALTER PROCEDURE [dbo].[i_UpdateBarcode] (
	@ID varchar(10),
	@R1 varchar(30), 
	@R2 varchar(20), 
	@R3 varchar(10), 
	@R4 varchar(50), 
	@isDel bit,
	@SetChange bit = 1
)
AS
BEGIN
	SET NOCOUNT ON;
	
	SET @ID	= dbo.sms_string(@ID)
	SET @R1	= dbo.sms_string(@R1)
	SET @R2	= dbo.sms_string(@R2)
	SET @R3	= dbo.sms_string(@R3)
	SET @R4	= dbo.sms_string(@R4)

	IF EXISTS ( SELECT * FROM dbo.Barcode (NOLOCK) WHERE ID = @ID AND R2 = @R2 )
		UPDATE dbo.Barcode SET R1 = @R1, R3 = @R3, R4 = @R4 WHERE ID = @ID AND R2 = @R2
	ELSE
		INSERT INTO dbo.Barcode VALUES (@ID, @R1, @R2, @R3, @R4, @isDel)

	IF @SetChange = 1
		INSERT INTO dbo.CashChanges SELECT
			ID,
			OBJECT_ID('Barcode'),
			@ID,
			@R2,
			0,
			0
		FROM
			dbo.Cash (NOLOCK)
		WHERE
			Mode = 1
			-- Элемента нет в очереди на выгрузку
			AND NOT EXISTS ( SELECT * FROM dbo.CashChanges (NOLOCK) WHERE CashID = ID AND TableID = OBJECT_ID('Barcode') AND R1 = @ID AND R2 = @R2 AND DO = 0 )
END

Клиент №2 должен прочесть данные из CashChanges, но только после всех вызовов своей процедуры. У меня был вариант с доп таблицей, куда клиент 1 вешал флаг, а второй клиент считывал флаг. Но в таком случае возможен случай, когда клиент 1 отваливается, то флаг поменять уже не кому.

Еще думал вариант писать не в CashChanges, а в #CashChanges, а потом переносить (в достаточно быстрой транзакции), но как выяснил #Table не видна в разных EXEC. А вариант с ##Table мне не нравится, потому как, может быть 2 клиента №1.

Вот и пытаюсь задействовать блокировки. Только пока не могу понять куда прописывать все эти параметры. т.е. Понятно, что
set transaction isolation level snapshot
перед селектом. А вот что делать с
READ_COMMITTED_SNAPSHOT
ALLOW_SNAPSHOT_ISOLATION
пока не ясно
22 сен 09, 13:43    [7692303]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
zenik
Member

Откуда:
Сообщений: 100
baracs
Вы на версию сервера в начале топика обратили внимание?

Это намек на то, что это не мой случай? А у меня выходит клиника? Или все же есть варианты?
22 сен 09, 13:45    [7692319]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с транзакциями/блокировками  [new]
Glory
Member

Откуда:
Сообщений: 104760
zenik
Glory
И зачем ваш Клиентом №2 собирается читать всю таблицу ?

Так она для него и пишется :) Как же не прочитать...

Для примера запрос клиента 1:

Я не вижу тут чтения всей таблицы. Я вижу тут чтение одной записи - WHERE ID = @ID AND R2 = @R2
Взаимоблокировки для такой задачи решаются простым созданием нужных индексов.
Чтобы коннекты просто даже не пытались лезть к заблокированным данным
22 сен 09, 13:49    [7692348]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить