Megosztás a következőn keresztül:


Az adatbázis-műveletekkel való ütközések elkerülése a FILESTREAM-alkalmazásokban

A következőkre vonatkozik:SQL Server

Azok az alkalmazások, amelyek az SqlOpenFilestream() használatával nyitják meg a Win32 fájlkezelőket a FILESTREAM BLOB-adatok olvasásához vagy írásához, ütközési hibákba ütközhetnek Transact-SQL gyakori tranzakcióban kezelt utasítások esetén. Ide tartoznak Transact-SQL vagy MARS-lekérdezések, amelyek végrehajtása hosszú időt vesz igénybe. Az alkalmazásokat gondosan kell megtervezni az ilyen típusú ütközések elkerülése érdekében.

Amikor az SQL Server adatbázismotorja vagy -alkalmazásai megpróbálják megnyitni a FILESTREAM BLOB-okat, az adatbázismotor ellenőrzi a társított tranzakciós környezetet. Az adatbázismotor engedélyezi vagy tagadja a kérést attól függően, hogy a nyitott művelet DDL-utasításokkal, DML-utasításokkal, adatok beolvasásával vagy tranzakciók kezelésével működik-e. Az alábbi táblázat bemutatja, hogyan határozza meg az adatbázismotor, hogy egy Transact-SQL utasítás engedélyezve vagy megtagadva legyen-e a tranzakcióban megnyitott fájlok típusa alapján.

Transact-SQL kijelentések Olvasásra megnyitva Írásra megnyitva
Az adatbázis metaadataival (például CREATE TABLE, CREATE INDEX, DROP TABLE és ALTER TABLE) dolgozó DDL-utasítások. Megengedett Blokkolva vannak, és időtúllépés miatt meghiúsulnak.
Az adatbázisban tárolt adatokkal (például UPDATE, DELETE és INSERT) dolgozó DML-utasítások. Megengedett Elutasítva
Kiválasztani Megengedett Megengedett
VÉGLEGESÍTÉSI TRANZAKCIÓ Elutasítva* Elutasítva*.
TRANZAKCIÓ MENTÉSE Elutasítva Elutasítva*
VISSZAÁLLÍTÁS Megengedett* Megengedett*

* A tranzakció megszakad, és a tranzakciókörnyezet nyitott leírói érvénytelenítve lesznek. Az alkalmazásnak be kell zárnia az összes nyitott fogantyút.

Példák

Az alábbi példák bemutatják, hogyan okozhat ütközéseket Transact-SQL utasítások és a FILESTREAM Win32-hozzáférés.

Egy. FÁJLSTREAM BLOB megnyitása írási hozzáféréshez

Az alábbi példa egy fájl csak írási hozzáférésre való megnyitásának hatását mutatja be.

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. FÁJLSTREAM BLOB megnyitása olvasási hozzáféréshez

Az alábbi példa egy fájl csak olvasási hozzáférésre való megnyitásának hatását mutatja be.

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. Több FILESTREAM BLOB-fájl megnyitása és bezárása

Ha több fájl is meg van nyitva, a rendszer a legkorlátozóbb szabályt használja. Az alábbi példa két fájlt nyit meg. Az első fájl meg van nyitva olvasásra, a második pedig írásra. A DML-utasítások a második fájl megnyitásáig le lesznek tagadva.

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. Nem sikerült bezárni a kurzort

Az alábbi példa bemutatja, hogy egy nem bezárt utasításkurzor hogyan akadályozhatja meg OpenSqlFilestream() a BLOB megnyitását az írási hozzáféréshez.

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.  

Lásd még:

FILESTREAM adatok elérése az OpenSqlFilestream használatával
több aktív eredményhalmaz (MARS)