Win32 i konflikty języka Transact-SQL

Aplikacje używające SqlOpenFilestream() do otwierania dojść Win32 do pliku do odczytu lub zapisu danych BLOB FILESTREAM mogą wystąpić błędy konflikt z Transact-SQL instrukcje, które są zarządzane przy użyciu typowych transakcji. Dotyczy to również Transact-SQL lub zająć dużo czas na zakończenie wykonywania kwerendy MARS. Aplikacje muszą być dokładnie zaprojektowane w celu uniknięcia tego typu konflikty.

Kiedy SQL Server Database Engine aplikacje spróbuje otworzyć FILESTREAM bloków BLOB, Database Engine sprawdza, czy kontekst transakcji skojarzony. The Database Engine allows or denies the request based on whether the open operation is working with DDL statements, DML statements, retrieving data, or managing transactions.Następujące tabela ilustruje sposób Database Engine Określa, czy Transact-SQL Instrukcja będzie być dozwolone lub nie, w zależności od typu plików, które są otwarte w transakcji.

Instrukcje języka Transact-SQL

Otwarty do odczytu

Otwarty do zapisu

Instrukcje DDL, pracować metadane bazy danych, takie jak CREATE tabela, DROP tabela, CREATE INDEX i instrukcji ALTER tabela.

Dozwolone

Są zablokowane, a kończą się niepowodzeniem z limit czas.

Instrukcje DML, pracować z danymi przechowywanymi w bazie danych, takich jak UPDATE, DELETE oraz INSERT.

Dozwolone

Odmowa

WYBIERZ OPCJĘ

Dozwolone

Dozwolone

zatwierdzanie TRANSAKCJI

Odmowa *

Odmowa *.

ZAPISYWANIE TRANSAKCJI

Odmowa *

Odmowa *

WYCOFYWANIE

Dozwolone *

Dozwolone *

* Transakcji zostało anulowane, a otwartych dojść do kontekstu transakcji są unieważnione.Aplikacja, należy zamknąć wszystkie otwarte dojścia.

Przykłady

Poniższych przykładach jak Transact-SQL instrukcje i Win32 FILESTREAM dostępu mogą powodować konflikty.

A.Otwieranie BLOB FILESTREAM, aby uzyskać dostęp do zapisu

Poniższy przykład przedstawia wynik po otworzeniu pliku do zapisu tylko.

dstHandle =  OpenSqlFilestream(dstFilePath, Write, 0,
    transactionToken, cbTransactionToken, 0);

//Write some date to the FILESTREAM BLOB.
WriteFile(dstHandle, updateData, …);

//DDL statements will be denied.
//DML statements will be denied.
//SELECT statements will be allowed. The FILESTREAM BLOB is
//returned without the modifications that are made by
//WriteFile(dstHandle, updateData, …).
CloseHandle(dstHandle);

//DDL statements will be allowed.
//DML statements will be allowed.
//SELECT statements will be allowed. The FILESTREAM BLOB
//is returned with the updateData applied.

B.Otwieranie BLOB FILESTREAM do odczytu

Poniższy przykład przedstawia wynik po otworzeniu pliku do odczytu tylko.

dstHandle =  OpenSqlFilestream(dstFilePath, Read, 0,
    transactionToken, cbTransactionToken, 0);
//DDL statements will be denied.
//DML statements will be allowed. Any changes that are
//made to the FILESTREAM BLOB will not be returned until
//the dstHandle is closed.
//SELECT statements will be allowed.
CloseHandle(dstHandle);

//DDL statements will be allowed.
//DML statements will be allowed.
//SELECT statements will be allowed.

C.Otwierania i zamykania wielu plików FILESTREAM BLOB

Jeśli pliki są otwarte, używana jest reguła najbardziej restrykcyjne.W poniższym przykładzie otwierany dwa pliki.Pierwszy plik jest otwarty do odczytu, a drugi do zapisu.Instrukcje DML zostaną odrzucone, aż do otwarcia drugiego pliku.

dstHandle =  OpenSqlFilestream(dstFilePath, Read, 0,
    transactionToken, cbTransactionToken, 0);
//DDL statements will be denied.
//DML statements will be allowed.
//SELECT statements will be allowed.

dstHandle1 =  OpenSqlFilestream(dstFilePath1, Write, 0,
    transactionToken, cbTransactionToken, 0);

//DDL statements will be denied.
//DML statements will be denied.
//SELECT statements will be allowed.

//Close the read handle. The write handle is still open.
CloseHandle(dstHandle);
//DML statements are still denied because the write handle is open.

//DDL statements will be denied.
//DML statements will be denied.
//SELECT statements will be allowed.

CloseHandle(dstHandle1);
//DDL statements will be allowed.
//DML statements will be allowed.
//SELECT statements will be allowed.

D.Nie można wykonać, aby zamknąć kursor

W poniższym przykładzie pokazano, w jaki sposób można zapobiec kursor instrukcja, które nie zostaną zamknięte OpenSqlFilestream() Otwieranie BLOB, aby uzyskać dostęp do zapisu.

TCHAR *sqlDBQuery =
TEXT("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT(),")
TEXT("Chart.PathName() FROM Archive.dbo.Records");

//Execute a long-running Transact-SQL statement. Do not allow
//the statement to complete before trying to
//open the file.

SQLExecDirect(hstmt, sqlDBQuery, SQL_NTS);

//Before you call OpenSqlFilestream() any open files
//that the Cursor the Transact-SQL statement is using
// must be closed. In this example,
//SQLCloseCursor(hstmt) is not called so that
//the transaction will indicate that there is a file
//open for reading. This will cause the call to
//OpenSqlFilestream() to fail because the file is
//still open.

HANDLE srcHandle =  OpenSqlFilestream(srcFilePath,
     Write, 0,  transactionToken,  cbTransactionToken,  0);

//srcHandle will == INVALID_HANDLE_VALUE because the
//cursor is still open.