Lezen in het Engels

Delen via


Conflicten voorkomen met databasebewerkingen in FILESTREAM-toepassingen

van toepassing op:SQL Server-

Toepassingen die sqlOpenFilestream() gebruiken om Win32-bestandsingangen te openen voor het lezen of schrijven van FILESTREAM BLOB-gegevens, kunnen conflictfouten tegenkomen met Transact-SQL instructies die worden beheerd in een gemeenschappelijke transactie. Dit omvat Transact-SQL- of MARS-query's die lang duren voordat de uitvoering is voltooid. Toepassingen moeten zorgvuldig zijn ontworpen om dergelijke conflicten te voorkomen.

Wanneer SQL Server Database Engine of toepassingen FILESTREAM-BLOBs proberen te openen, controleert de database-engine de bijbehorende transactiecontext. De database-engine staat de aanvraag toe of weigert deze op basis van of de open bewerking werkt met DDL-instructies, DML-instructies, het ophalen van gegevens of het beheren van transacties. In de volgende tabel ziet u hoe de database-engine bepaalt of een Transact-SQL instructie wordt toegestaan of geweigerd op basis van het type bestanden dat in de transactie is geopend.

Transact-SQL verklaringen Geopend voor lezen Geopend voor schrijven
DDL-instructies die werken met databasemetagegevens, zoals CREATE TABLE, CREATE INDEX, DROP TABLE en ALTER TABLE. Toegestaan Worden geblokkeerd en mislukken door een time-out.
DML-instructies die werken met de gegevens die zijn opgeslagen in de database, zoals UPDATE, DELETE en INSERT. Toegestaan Geweigerd
SELECTEREN Toegestaan Toegestaan
DOORVOERTRANSACTIE Geweigerd* Geweigerd*.
TRANSACTIE OPSLAAN Geweigerd* Geweigerd*
TERUGDRAAIEN Toegestaan* Toegestaan*

* De transactie wordt geannuleerd en geopende ingangen voor de transactiecontext zijn ongeldig. De toepassing moet alle geopende ingangen sluiten.

Voorbeelden

In de volgende voorbeelden ziet u hoe Transact-SQL instructies en FILESTREAM Win32-toegang conflicten kunnen veroorzaken.

Een. Een FILESTREAM-BLOB openen voor schrijftoegang

In het volgende voorbeeld ziet u het effect van het openen van een bestand voor alleen schrijftoegang.

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. Een FILESTREAM-BLOB openen voor leestoegang

In het volgende voorbeeld ziet u het effect van het openen van een bestand voor alleen-lezentoegang.

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. Meerdere FILESTREAM BLOB-bestanden openen en sluiten

Als er meerdere bestanden zijn geopend, wordt de meest beperkende regel gebruikt. In het volgende voorbeeld worden twee bestanden geopend. Het eerste bestand wordt geopend voor lezen en het tweede voor schrijven. DML-instructies worden geweigerd totdat het tweede bestand wordt geopend.

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. Kan een cursor niet sluiten

In het volgende voorbeeld ziet u hoe een instructiecursor die niet is gesloten, kan voorkomen dat OpenSqlFilestream() de BLOB opent voor schrijftoegang.

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.  

Zie ook

Toegang tot FILESTREAM-gegevens met OpenSqlFilestream
MARS (Multiple Active Result Sets) gebruiken