GET FILESTREAM TRANSACTION CONTEXT: примеры (SQL)

Руководство по GET_FILESTREAM_TRANSACTION_CONTEXT в SQL Server
Раздел: Функции потокового ввода-вывода, Filestream
GET_FILESTREAM_TRANSACTION_CONTEXT: varbinary(8192)

Описание функции GET_FILESTREAM_TRANSACTION_CONTEXT

Функция GET_FILESTREAM_TRANSACTION_CONTEXT() в MS SQL Server возвращает контекст текущей транзакции в виде набора байтов для операций с данными FILESTREAM. Этот контекст требуется приложению для выполнения операций файлового ввода-вывода через API Win32 для работы с файлами FILESTREAM напрямую в файловой системе, обеспечивая согласованность транзакций.

Функция используется в сценариях, когда доступ к файлам FILESTREAM происходит не через T-SQL, а через файловую систему с помощью потокового API. Это позволяет управлять файлами с сохранением атомарности, согласованности, изоляции и долговечности (ACID) транзакций.

Аргументы: функция не принимает параметров.

Возвращаемое значение: varbinary(128). Возвращает токен контекста транзакции для текущего сеанса. Если функция вызвана вне активной транзакции, возвращается значение NULL. Токен необходим для передачи в функции Win32, такие как OpenSqlFilestream.

Короткие примеры использования

-- Пример 1: Получение контекста в явной транзакции
BEGIN TRANSACTION;
SELECT GET_FILESTREAM_TRANSACTION_CONTEXT() AS TransactionContext;
COMMIT;
TransactionContext
0x00000000000000000000000000000000...
-- Пример 2: Вызов вне транзакции
SELECT GET_FILESTREAM_TRANSACTION_CONTEXT() AS TransactionContext;
TransactionContext
NULL

Похожие функции MS SQL

В MS SQL Server прямых аналогов функции нет. Однако для управления транзакциями используются другие функции:

  • @@TRANCOUNT – возвращает количество активных транзакций для текущего соединения. Используется для проверки состояния транзакции, но не предоставляет контекст для FILESTREAM.
  • XACT_STATE() – указывает состояние текущей транзакции (активна, завершена, ошибка). Помогает управлять транзакциями, но не связана с FILESTREAM.

Предпочтительнее использовать GET_FILESTREAM_TRANSACTION_CONTEXT() именно для интеграции с файловой системой через Win32 API.

Альтернативы в других СУБД и языках

Концепция FILESTREAM специфична для MS SQL Server. Однако другие СУБД предлагают аналогичные механизмы хранения больших двоичных объектов (BLOB):

  • PostgreSQL: Тип данных bytea или Large Objects с поддержкой транзакций через функции lo_import, lo_export. Пример:
BEGIN;
SELECT lo_open(lo_create(0), 131072);
COMMIT;
  • Oracle: Тип BLOB с доступом через DBMS_LOB пакет. Пример:
DECLARE
  lob_loc BLOB;
BEGIN
  INSERT INTO files VALUES (1, EMPTY_BLOB()) RETURNING data INTO lob_loc;
  DBMS_LOB.OPEN(lob_loc, DBMS_LOB.LOB_READWRITE);
END;
  • MySQL: Тип LONGBLOB без встроенного транзакционного доступа через файловую систему. Работа через стандартные запросы.
  • SQLite: BLOB хранятся как обычные данные, транзакции управляются на уровне SQL.

Отличие MS SQL – интеграция с файловой системой через контекст транзакции.

Типичные ошибки

  • Вызов вне транзакции: Функция возвращает NULL, что может вызвать ошибки в клиентском коде.
-- Ошибка: нет активной транзакции
SELECT GET_FILESTREAM_TRANSACTION_CONTEXT();
NULL
  • Использование несовместимой СУБД: Функция доступна только в редакциях SQL Server с поддержкой FILESTREAM.
  • Утечка контекста: Не освобождение ресурсов Win32 после использования контекста может блокировать файлы.

Изменения в последних версиях

Функция не претерпела значительных изменений с момента введения FILESTREAM в SQL Server 2008. В SQL Server 2012 добавлена интеграция с FileTable, но работа функции осталась прежней. В современных версиях (2019, 2022) функция поддерживается без изменений синтаксиса или поведения.

Расширенные примеры использования

Пример 1: Клиентское приложение на C# с использованием контекста для записи файла.

Пример sql
-- T-SQL часть: начало транзакции и получение контекста
BEGIN TRANSACTION;
DECLARE @context VARBINARY(128);
SET @context = GET_FILESTREAM_TRANSACTION_CONTEXT();
SELECT file_path, @context AS tx_context FROM documents WHERE id = 1;
-- Далее транзакция остается открытой для клиентского кода

Пример 2: Комплексная вставка с FILESTREAM через Win32.

Пример sql
-- Создание таблицы с FILESTREAM
CREATE TABLE FileTable (
    id UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,
    file_data VARBINARY(MAX) FILESTREAM NULL,
    file_path NVARCHAR(500)
);
GO
-- Вставка записи и получение контекста для последующей записи файла
BEGIN TRANSACTION;
INSERT INTO FileTable (id, file_path) VALUES (NEWID(), 'C:\temp\file.txt');
SELECT 
    file_data.PathName() AS file_path,
    GET_FILESTREAM_TRANSACTION_CONTEXT() AS tx_context
FROM FileTable WHERE id = (SELECT MAX(id) FROM FileTable);
-- Клиентский код использует file_path и tx_context для записи через Win32
COMMIT;

Пример 3: Использование в процедуре с обработкой ошибок.

Пример sql
CREATE PROCEDURE InsertFileWithContext
AS
BEGIN
    DECLARE @context VARBINARY(128);
    BEGIN TRANSACTION;
    BEGIN TRY
        SET @context = GET_FILESTREAM_TRANSACTION_CONTEXT();
        IF @context IS NULL
            THROW 51000, 'Требуется активная транзакция', 1;
        -- Логика работы с FILESTREAM
        COMMIT;
    END TRY
    BEGIN CATCH
        ROLLBACK;
        THROW;
    END CATCH
END;

MS SQL GET_FILESTREAM_TRANSACTION_CONTEXT function comments

En
GET FILESTREAM TRANSACTION CONTEXT Returns the transaction context for a session