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

Откуда:
Сообщений: 1197
Привет.
Играюсь с уровнями изоляций и не могу понять почему виснет запрос

Действие 1.

открываю 2 окна в студии.
в первое вставляем такой код

set tran isolation level Read committed
begin tran

	   waitfor  delay '00:00:10' 
	  
  	   insert [test].[dbo].[Stores]	
	   select 12, 22, 23, 24
	   
	   waitfor  delay '00:00:10'   
	  
commit tran


во второе вставляем такой

set tran isolation level  Read committed
begin tran
	   insert [test].[dbo].[Stores]	 
	   select 1, 2, 3, 4
	   
	   waitfor  delay '00:00:15' 
	   
	   SELECT * FROM [test].[dbo].[Stores]  
commit tran
 


сначала запускаю первый запрос и тут же запускаю второй так чтобы в первом запросе ну успел закончиться waitfor delay '00:00:10'.

В итоге первый запрос отрабатывает, а второй постоянно виснет. причем открытые нового окна не помогает.
объясните почему так?
14 ноя 12, 22:46    [13475288]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
relief
Привет.
Играюсь с уровнями изоляций и не могу понять почему виснет запрос

Действие 1.

открываю 2 окна в студии.
в первое вставляем такой код

set tran isolation level Read committed
begin tran

	   waitfor  delay '00:00:10' 
	  
  	   insert [test].[dbo].[Stores]	
	   select 12, 22, 23, 24
	   
	   waitfor  delay '00:00:10'   
	  
commit tran


во второе вставляем такой

set tran isolation level  Read committed
begin tran
	   insert [test].[dbo].[Stores]	 
	   select 1, 2, 3, 4
	   
	   waitfor  delay '00:00:15' 
	   
	   SELECT * FROM [test].[dbo].[Stores]  
commit tran
 


сначала запускаю первый запрос и тут же запускаю второй так чтобы в первом запросе ну успел закончиться waitfor delay '00:00:10'.

В итоге первый запрос отрабатывает, а второй постоянно виснет. причем открытые нового окна не помогает.
объясните почему так?
А как он вам прочитает заблокированные данные?
14 ноя 12, 22:56    [13475317]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
select @@version
15 ноя 12, 00:44    [13475754]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
кстати да, во всех остальных окнах выполните rollback transaction
15 ноя 12, 00:47    [13475765]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Mind
relief
Привет.
Играюсь с уровнями изоляций и не могу понять почему виснет запрос

Действие 1.

открываю 2 окна в студии.
в первое вставляем такой код

set tran isolation level Read committed
begin tran

	   waitfor  delay '00:00:10' 
	  
  	   insert [test].[dbo].[Stores]	
	   select 12, 22, 23, 24
	   
	   waitfor  delay '00:00:10'   
	  
commit tran


во второе вставляем такой

set tran isolation level  Read committed
begin tran
	   insert [test].[dbo].[Stores]	 
	   select 1, 2, 3, 4
	   
	   waitfor  delay '00:00:15' 
	   
	   SELECT * FROM [test].[dbo].[Stores]  
commit tran
 


сначала запускаю первый запрос и тут же запускаю второй так чтобы в первом запросе ну успел закончиться waitfor delay '00:00:10'.

В итоге первый запрос отрабатывает, а второй постоянно виснет. причем открытые нового окна не помогает.
объясните почему так?
А как он вам прочитает заблокированные данные?


как я все понимаю.
1. запускаем поток 1 из первого окна
2. поток 1 уходит в таймаут на 10 секунд
3. запускаем поток 2 из второго окна
4. поток 2 вставляет данные
5. поток 2 уходит в таймаут на 15 секунд
6. поток 1 просыпается
7. поток 1 вставляет данные
8. поток 1 засыпает на 10 секунд
9. поток 2 просыпается и вот тут непонятка

10. В МОЕМ понимании он должен в селекте вернуть закоммиченные данные. я же ему сказал read commited
но даже если он не может вернуть, он должен подождать пока закончится второй таймаут в потоке 1 и потом вернуть данные
15 ноя 12, 10:00    [13476343]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
relief,

Во первых, версию сиквела покажите.
Во вторых, ваша ООПшная логика работы сдесь не канает, потому как НЕТ никаких потоков, а есть соединения.
И второе есть блокировки данных и их можно видеть с помощью соответствующих команд (sp_lock) и гадать почему, когда есть возможность увидеть истину, это бред.
15 ноя 12, 10:29    [13476497]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
relief
В МОЕМ понимании он должен в селекте вернуть закоммиченные данные. я же ему сказал read commited
но даже если он не может вернуть, он должен подождать пока закончится второй таймаут в потоке 1 и потом вернуть данные
И что тут непонятного? Как он должен прочитать еще незакомиченные данные, вставленные в первом потоке?
15 ноя 12, 10:42    [13476585]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Гавриленко Сергей Алексеевич
relief
В МОЕМ понимании он должен в селекте вернуть закоммиченные данные. я же ему сказал read commited
но даже если он не может вернуть, он должен подождать пока закончится второй таймаут в потоке 1 и потом вернуть данные
И что тут непонятного? Как он должен прочитать еще незакомиченные данные, вставленные в первом потоке?


так я же говорю серверу в начале транзакции
set tran isolation level  Read committed

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


где я что не так понимаю?
15 ноя 12, 10:59    [13476697]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Glory
Member

Откуда:
Сообщений: 104760
relief
.е. читай только закоммиченные данные.

Ну так он и ждет, когда ВСЕ коннекты закоммитят данные.
15 ноя 12, 11:21    [13476834]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
invm
Member

Откуда: Москва
Сообщений: 9397
relief
так я же говорю серверу в начале транзакции
set tran isolation level  Read committed

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


где я что не так понимаю?
У вас пока что превратное представление об уровнях изоляции транзакций. Для начала -- Уровень изолированности транзакций
15 ноя 12, 11:27    [13476876]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Glory
relief
.е. читай только закоммиченные данные.

Ну так он и ждет, когда ВСЕ коннекты закоммитят данные.


теперь понял.
а тогда дальше непонятно.

5. поток 2 уходит в таймаут на 15 секунд
6. поток 1 просыпается
7. поток 1 вставляет данные
8. поток 1 засыпает на 10 секунд

9. делает коммит
10. и тут по идее поток 2 должен получить инфу, что поток 1 замоммитил все и выполнить селект
15 ноя 12, 11:45    [13476998]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Glory
Member

Откуда:
Сообщений: 104760
relief
10. и тут по идее поток 2 должен получить инфу, что поток 1 замоммитил все и выполнить селект

Не по идеи, а действительно.

ЗЫ
И зачем это игра с delay, если просто можно выполнять в нужном порядке команды в разных коннектах вручную

коннект 1 begin tran
коннект 2 begin tran
коннект 2 insert [test].[dbo].[Stores] select 1, 2, 3, 4
коннект 1 insert [test].[dbo].[Stores] select 12, 22, 23, 24
коннект 2 SELECT * FROM [test].[dbo].[Stores]
коннект 1 commit tran
коннект 2 commit tran
15 ноя 12, 11:54    [13477058]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Glory
relief
10. и тут по идее поток 2 должен получить инфу, что поток 1 замоммитил все и выполнить селект

Не по идеи, а действительно.


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

Glory
ЗЫ
И зачем это игра с delay, если просто можно выполнять в нужном порядке команды в разных коннектах вручную

коннект 1 begin tran
коннект 2 begin tran
коннект 2 insert [test].[dbo].[Stores] select 1, 2, 3, 4
коннект 1 insert [test].[dbo].[Stores] select 12, 22, 23, 24
коннект 2 SELECT * FROM [test].[dbo].[Stores]
коннект 1 commit tran
коннект 2 commit tran


действительно. благодарю
15 ноя 12, 11:58    [13477092]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Glory
Member

Откуда:
Сообщений: 104760
relief
так вот вся соль, что селект второго коннекта не выполняется и запрос виснет намертво. собственно почему я топик и создал

Он не виснет, тем более намертво.
Он ждет снятия блокировок. Потому что вы указали ему прочитать подтвержденные данные
15 ноя 12, 12:10    [13477222]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
relief
Гавриленко Сергей Алексеевич
пропущено...
И что тут непонятного? Как он должен прочитать еще незакомиченные данные, вставленные в первом потоке?


так я же говорю серверу в начале транзакции
set tran isolation level  Read committed

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


где я что не так понимаю?
Не понимаете. read committed будет ждать снятия всех несовместимых блокировок, чтобы прочитать таки все закомиченные данные. А не только те, что вы закомитили в текущей транзакции.
15 ноя 12, 12:15    [13477266]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Glory
relief
так вот вся соль, что селект второго коннекта не выполняется и запрос виснет намертво. собственно почему я топик и создал

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


а что так долго снимается блокировка (минуту ждал не дождался) ?
база на домашнем компе тестовая - никто не юзает
15 ноя 12, 12:20    [13477313]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
relief
Glory
пропущено...

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


а что так долго снимается блокировка (минуту ждал не дождался) ?
база на домашнем компе тестовая - никто не юзает
Наверное, кто-то открыл больше транзакций, чем закрыл. Возьмите в привычку в начале скрипта писать if @@trancount > 0 rollback.
15 ноя 12, 12:24    [13477347]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
relief
Member

Откуда:
Сообщений: 1197
Гавриленко Сергей Алексеевич
relief
пропущено...


а что так долго снимается блокировка (минуту ждал не дождался) ?
база на домашнем компе тестовая - никто не юзает
Наверное, кто-то открыл больше транзакций, чем закрыл. Возьмите в привычку в начале скрипта писать if @@trancount > 0 rollback.


Понял. Спасибо! Будем играться дальше :)
15 ноя 12, 12:35    [13477421]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
invm
relief
так я же говорю серверу в начале транзакции
set tran isolation level  Read committed

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


где я что не так понимаю?
У вас пока что превратное представление об уровнях изоляции транзакций. Для начала -- Уровень изолированности транзакций


Я для горячих голово напомню, что стандарт описывает Read committed таким образом, что читатель не должен прочитать
записи, котоыре незакомичены ещё. А что при этом должно происходить -- не оговаривается. Одни реализации видят, что
запись уже есть, но ещё незакомичена и ждут комита. Другие реализации видят, что запись есть, но незакомичена, и не читают
её вообще, пропуская, потому что что существующая незакомиченная запись, что отсутствующая запись -- эквивалентно.

В MSSQL кстати есть хинт запроса READPAST, который переключает с первого поведения на второе.
15 ноя 12, 18:04    [13479911]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
MasterZiv
Я для горячих голово напомню, что стандарт описывает Read committed таким образом, что читатель не должен прочитать
записи, котоыре незакомичены ещё. А что при этом должно происходить -- не оговаривается. Одни реализации видят, что
запись уже есть, но ещё незакомичена и ждут комита. Другие реализации видят, что запись есть, но незакомичена, и не читают
её вообще, пропуская, потому что что существующая незакомиченная запись, что отсутствующая запись -- эквивалентно.

В MSSQL кстати есть хинт запроса READPAST, который переключает с первого поведения на второе.
Вообще есть две стратегии - блокировать и дожидаться снятия всех блокировок при чтении (блокировочник) и показывать при чтении последнюю версию данных до модификации (версионник). А readpast - это просто тупое скипанье заблокированных данных, чтение не пойми чего. Применяется в очень специфических случаях.
15 ноя 12, 18:07    [13479936]     Ответить | Цитировать Сообщить модератору
 Re: Почему виснет запрос?  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34619
Гавриленко Сергей Алексеевич
MasterZiv
Я для горячих голово напомню, что стандарт описывает Read committed таким образом, что читатель не должен прочитать
записи, котоыре незакомичены ещё. А что при этом должно происходить -- не оговаривается. Одни реализации видят, что
запись уже есть, но ещё незакомичена и ждут комита. Другие реализации видят, что запись есть, но незакомичена, и не читают
её вообще, пропуская, потому что что существующая незакомиченная запись, что отсутствующая запись -- эквивалентно.

В MSSQL кстати есть хинт запроса READPAST, который переключает с первого поведения на второе.
Вообще есть две стратегии - блокировать и дожидаться снятия всех блокировок при чтении (блокировочник) и показывать при чтении последнюю версию данных до модификации (версионник). А readpast - это просто тупое скипанье заблокированных данных, чтение не пойми чего. Применяется в очень специфических случаях.


Вообще, если подумаешь, то можно достаточно быстро додуматься до того, что

  • Если транзакция вставила новую запись и ещё не закомитилась, то логически (для приложения) это эквивалентно тому, что запись ещё вообще не вставилась.
  • Если транзакция изменила существующую запись (несколько полей в ней) и ещё не закомитилась, то логически (для приложения) это эквивалентно тому, что запись со старыми значениями полей удалилась, а новая запись с такими же значениями неизменённых полей и с новыми значениями для изменённых полей добавилась.

    Принимая всё это во внимание, READPAST не такая уж и бессмысленная штука, а не просто "тупое скипанье заблокированных данных".

    Кстати напомню, что в теории сериализации транзакций (которая порождает все эти уровни изоляции из стандарта) рассматриваются только две операции -- чтение и запись. Там нет ни INSERT, ни DELETE.
  • 15 ноя 12, 21:33    [13480744]     Ответить | Цитировать Сообщить модератору
     Re: Почему виснет запрос?  [new]
    invm
    Member

    Откуда: Москва
    Сообщений: 9397
    MasterZiv
  • Если транзакция вставила новую запись и ещё не закомитилась, то логически (для приложения) это эквивалентно тому, что запись ещё вообще не вставилась.
  • Если транзакция изменила существующую запись (несколько полей в ней) и ещё не закомитилась, то логически (для приложения) это эквивалентно тому, что запись со старыми значениями полей удалилась, а новая запись с такими же значениями неизменённых полей и с новыми значениями для изменённых полей добавилась.

    Принимая всё это во внимание, READPAST не такая уж и бессмысленная штука, а не просто "тупое скипанье заблокированных данных".
  • Наверное забавно будет наблюдать за какой-нибудь банковской или медицинской системой, где счета клиентов или медицинские карточки пациентов то исчезают, то вновь появляются :)
    15 ноя 12, 21:48    [13480790]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить