Evitare conflitti con le operazioni del database nelle applicazioni di FILESTREAMAvoid Conflicts with Database Operations in FILESTREAM Applications

Le applicazioni che usano SqlOpenFilestream() per aprire gli handle di file Win32 per la lettura o la scrittura di dati BLOB FILESTREAM possono entrare in conflitto con le istruzioni Transact-SQLTransact-SQL gestite in una transazione comune.Applications that use SqlOpenFilestream() to open Win32 file handles for reading or writing FILESTREAM BLOB data can encounter conflict errors with Transact-SQLTransact-SQL statements that are managed in a common transaction. Sono incluse le query Transact-SQLTransact-SQL o MARS la cui esecuzione richiede molto tempo.This includes Transact-SQLTransact-SQL or MARS queries that take a long time to finish execution. È necessario progettare con attenzione le applicazioni per evitare questi tipi di conflitti.Applications must be carefully designed to help avoid these types of conflicts.

Quando il Motore di database di SQL ServerSQL Server Database Engine o le applicazioni provano ad aprire dati BLOB FILESTREAM, il Motore di databaseDatabase Engine controlla il contesto di transazione associato.When Motore di database di SQL ServerSQL Server Database Engine or applications try to open FILESTREAM BLOBs, the Motore di databaseDatabase Engine checks the associated transaction context. Il Motore di databaseDatabase Engine consente o nega la richiesta a seconda che l'operazione di apertura funzioni o meno con le istruzioni DDL, le istruzioni DML, il recupero dei dati o la gestione delle transazioni.The Motore di databaseDatabase Engine allows or denies the request based on whether the open operation is working with DDL statements, DML statements, retrieving data, or managing transactions. Nella tabella seguente viene illustrato il modo in cui il Motore di databaseDatabase Engine determina se un 'istruzione Transact-SQLTransact-SQL verrà consentita o negata in base al tipo di file aperti nella transazione.The following table shows how the Motore di databaseDatabase Engine determines whether a Transact-SQLTransact-SQL statement will be allowed or denied based on the type of files that are open in the transaction.

istruzioni Transact-SQLTransact-SQL statements Aperte per l'accesso in letturaOpened for read Aperte per l'accesso in scritturaOpened for write
Istruzioni DDL che funzionano con i metadati del database, ad esempio CREATE TABLE, CREATE INDEX, DROP TABLE e ALTER TABLE.DDL statements that work with database metadata, such as CREATE TABLE, CREATE INDEX, DROP TABLE, and ALTER TABLE. AllowedAllowed Bloccate ed errore di timeout.Are blocked and fail with a time-out.
Istruzioni DML che funzionano con i dati archiviati nel database, ad esempio UPDATE, DELETE e INSERT.DML statements that work with the data that is stored in the database, such as UPDATE, DELETE, and INSERT. AllowedAllowed NegateDenied
SELECTSELECT AllowedAllowed AllowedAllowed
COMMIT TRANSACTIONCOMMIT TRANSACTION NegateDenied NegateDenied.
SAVE TRANSACTIONSAVE TRANSACTION NegateDenied NegateDenied
ROLLBACKROLLBACK ConsentiteAllowed ConsentiteAllowed

* La transazione viene annullata e gli handle aperti per il contesto di transazione vengono invalidati.* The transaction is canceled, and open handles for the transaction context are invalidated. L'applicazione deve chiudere tutti gli handle aperti.The application must close all open handles.

EsempiExamples

Gli esempi seguenti illustrano come le istruzioni Transact-SQLTransact-SQL e l'accesso Win32 FILESTREAM possano creare conflitti.The following examples show how Transact-SQLTransact-SQL statements and FILESTREAM Win32 access can cause conflicts.

A.A. Apertura di dati BLOB FILESTREAM per l'accesso in scritturaOpening a FILESTREAM BLOB for write access

Nell'esempio seguente viene mostrato l'effetto dell'apertura di un file per il solo accesso in scrittura.The following example shows the effect of opening a file for write access only.

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.B. Apertura di dati BLOB FILESTREAM per l'accesso in letturaOpening a FILESTREAM BLOB for read access

Nell'esempio seguente viene mostrato l'effetto dell'apertura di un file per il solo accesso in lettura.The following example shows the effect of opening a file for read access only.

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.C. Apertura e chiusura di più file BLOB FILESTREAMOpening and closing multiple FILESTREAM BLOB files

Se sono aperti più file, viene utilizzata la regola più restrittiva.If multiple files are open, the most restrictive rule is used. Nell'esempio seguente vengono aperti due file.The following example opens two files. Il primo file è aperto in lettura, il secondo in scrittura.The first file is opened for read and the second for write. Le istruzioni DML rimarranno negate finché non viene aperto il secondo file.DML statements will be denied until the second file is opened.

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.D. Chiusura non riuscita di un cursoreFailing to close a cursor

Nell'esempio seguente viene illustrato come un cursore dell'istruzione non chiuso possa impedire a OpenSqlFilestream() di aprire i dati BLOB per l'accesso in scrittura.The following example shows how a statement cursor that is not closed can prevent OpenSqlFilestream() from opening the BLOB for write access.

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.  

Vedere ancheSee Also

Accesso ai dati FILESTREAM con OpenSqlFilestream Access FILESTREAM Data with OpenSqlFilestream
Uso di MARS (Multiple Active Result Set) Using Multiple Active Result Sets (MARS)