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

Откуда:
Сообщений: 8
Есть FileTable, есть соответствующая расшаренная папка с файлами.
Файлы открываются, сохраняются и всё такое...
Запросы (SELECT, UPDATE, INSERT и всё такое...) к FileTable выполняются, НО если закрыты все файлы (или они открыты только на чтение).
Если файл(ы) открыт(ы) на запись SELECT виснет пока не закроешь файл(ы), хотя в MSDN например тут написано, что вроде как SELECT можно...
Причём виснет SELECT только на той записи, файл которой открыт на запись.
Как с этим бороться или если нельзя выполнять SQL-запросы при открытых файлах, зачем это всё нужно?
16 апр 13, 10:04    [14185451]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
И как вы делаете SELECT, поди к данным файла обращаетесь?
Ну и чё непонятного, сами же данные то он не может вернуть.

Ну вот я открыл файл на запись, и тупо удалил содержимое, как вы себе представляете, что должен вернуть SELECT для этого файла?!
Естественно, что его GUID не поменялся, и он нормально вернётся, а что в колонке данных (VarBinary(max))?!
16 апр 13, 14:54    [14187335]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
SELECT * FROM <FileTable>
Чёрт с ними с данными, тут понятно, хотя можно было бы и их вернуть (почему бы нет (для чтения)) на данный момент (в чём проблема?).
Но почему не возвращаются например name, а is_archive - без проблем?
16 апр 13, 15:32    [14187684]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
Glory
Member

Откуда:
Сообщений: 104760
a77x7
хотя можно было бы и их вернуть (почему бы нет (для чтения)) на данный момент (в чём проблема?).

Какие "на данный момент" ? Которые в неизвестном состоянии,потому что в процессе изменения в другом коннекте?

a77x7
Но почему не возвращаются например name, а is_archive - без проблем?

И вы уже посмотрели в мониторе, чего ожидает ваш запрос ?
16 апр 13, 15:35    [14187710]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Glory
a77x7
хотя можно было бы и их вернуть (почему бы нет (для чтения)) на данный момент (в чём проблема?).

Какие "на данный момент" ? Которые в неизвестном состоянии,потому что в процессе изменения в другом коннекте?

Они же не меняются постоянно (каждую миллисекунду), а скорее всего только внутри транзакции, а транзакция по идее должна начинаться только в момент начала записи (Win32 WriteFile, т.е. например, тогда когда пользователь нажмёт ^S) и закрываться сразу после записи. Хотя я не могу это утверждать конечно (не так глубоки мои знания в этом плане).

Glory
a77x7
Но почему не возвращаются например name, а is_archive - без проблем?

И вы уже посмотрели в мониторе, чего ожидает ваш запрос ?

Вот это я как раз не умею...
Ну вот попытался:
Тип блокировки: LCK_M_S
17 апр 13, 07:34    [14190182]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Снимок экрана монитора...

К сообщению приложен файл. Размер - 105Kb
17 апр 13, 07:44    [14190187]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
Glory
Member

Откуда:
Сообщений: 104760
a77x7
Они же не меняются постоянно (каждую миллисекунду), а скорее всего только внутри транзакции, а транзакция по идее должна начинаться только в момент начала записи (Win32 WriteFile, т.е. например, тогда когда пользователь нажмёт ^S) и закрываться сразу после записи. Хотя я не могу это утверждать конечно (не так глубоки мои знания в этом плане).

Вот именно, что лучше сначала узнать, когда у вас началась транзакция и что в ней заблокировано

a77x7
Вот это я как раз не умею...
Ну вот попытался:
Тип блокировки: LCK_M_S

У вас там даже видно, какой ресурс и как заблокирован
Х - это эксклюзивная блокировка
17 апр 13, 10:52    [14190949]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Немного яснее становится.
Глубже копать думаю нет смысла.
Я просто думал, может это где-то какой-то галочкой регулируется.
Не понимаю, тогда зачем давать возможность доступа к таким файлам через расшаренную папку, если после этого невозможно выполнять запросы к FileTable.
(Я планировал применить это для системы документооборота. Обычно в таких системах работа с файлами делается через выгрузку их во временную папку, и потом загрузку обратно в базу. А тут вроде, вот тебе файл, вот метаданные и всё одном месте, не нужно особо ничего синхронизировать ни каких временных папок.)
Получается как только открывается файл метаданные тоже становятся недоступными...
Думаю, может как-то через триггеры, перед открытием файлов, складывать их имена, id-шники и т.п. в отдельную таблицу и исключать их потом из запросов к FileTable (?).
17 апр 13, 13:36    [14192534]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
Glory
Member

Откуда:
Сообщений: 104760
a77x7
Получается как только открывается файл метаданные тоже становятся недоступными...

Интересно, а из чего следуют такие выводы ?

a77x7
Думаю, может как-то через триггеры, перед открытием файлов, складывать их имена, id-шники и т.п. в отдельную таблицу и исключать их потом из запросов к FileTable (?).

Вы хотите выбрать данные, заблокированные другим коннектом.
Сервер не даст вам это сделать ни для Filestream, ни для любого другого типа данных.
Потому что блокировки - это стадартный механизм сервера предназначенный как раз для регулирования совместного доступа.
17 апр 13, 13:43    [14192591]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Glory
a77x7
Получается как только открывается файл метаданные тоже становятся недоступными...

Интересно, а из чего следуют такие выводы ?

Ну, например, поле name я уже не могу получить.

[quot Glory]
a77x7
Думаю, может как-то через триггеры, перед открытием файлов, складывать их имена, id-шники и т.п. в отдельную таблицу и исключать их потом из запросов к FileTable (?).
Вы хотите выбрать данные, заблокированные другим коннектом.
Сервер не даст вам это сделать ни для Filestream, ни для любого другого типа данных.
Потому что блокировки - это стадартный механизм сервера предназначенный как раз для регулирования совместного доступа.

Сделать временные копии этих данных до блокировки.

Но это уже больше на извращение походит.
17 апр 13, 14:02    [14192715]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
Glory
Member

Откуда:
Сообщений: 104760
a77x7
Ну, например, поле name я уже не могу получить.

Значение поля - это не метаданные.
Если заблокирована запись, то вы не можете прочитать ни одно поле записи.

a77x7
Сделать временные копии этих данных до блокировки.
Но это уже больше на извращение походит.

Все уже давно придумано в READ_COMMITTED_SNAPSHOT/ALLOW_SNAPSHOT_ISOLATION
17 апр 13, 15:30    [14193323]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Под метаданными я имел ввиду данные описывающие файлы, где файлы - это записи (поле file_stream) в FileTable, и которые доступны также как обычные файлы NTFS. (Насколько я понял из MSDN, поле name, например, нужно только лишь для того, чтобы отображать имя файла для доступа к нему стандартными средствами Win32 API).

Про READ_COMMITTED_SNAPSHOT/ALLOW_SNAPSHOT_ISOLATION буду читать, пока глянул, вроде что-то интересное для моего случая. Возможно это как раз та галочка про которую я думаю...

Быстренько попробовал - теперь запросы выполняются. Буду детально разбираться.
Только если в SELECT-е в списке полей указать file_stream, то получаем:
SQL Server 2012:
Невозможен доступ к столбцу file_stream в объекте FileTable "PhotoFiles", поскольку объект FileTable не поддерживает управление версиями строк. Необходимо установить уровень транзакции, отличный от READ COMMITTED SNAPSHOT или SNAPSHOT, либо использовать табличное указание READCOMMITTEDLOCK.

Ну в принципе - это наверно вполне логично. Я так понимаю в таком случае реальный запрос выполняется уже к tempdb. Не будет же SQL Server делать копии (версии) FILESTREAM...
Спасибо, Glory - это похоже то что нужно.
17 апр 13, 17:21    [14194232]     Ответить | Цитировать Сообщить модератору
 Re: FILESTREAM: SELECT при открытых файлах (SQL Server 2012)  [new]
a77x7
Member

Откуда:
Сообщений: 8
Думаю мне вообще достаточно этого:
SELECT TOP 1000 [stream_id]
      ,[file_stream]
      ,[name]
      ,[path_locator]
      ,[parent_path_locator]
      ,[file_type]
      ,[cached_file_size]
      ,[creation_time]
      ,[last_write_time]
      ,[last_access_time]
      ,[is_directory]
      ,[is_offline]
      ,[is_hidden]
      ,[is_readonly]
      ,[is_archive]
      ,[is_system]
      ,[is_temporary]
  FROM [PhotoLibrary].[dbo].[PhotoFiles]
  WITH (READUNCOMMITTED)

Так даже file_stream возвращается.
17 апр 13, 17:55    [14194494]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить