Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
platí pro:SQL Server
Aplikace, které používají SqlOpenFilestream() k otevření popisovačů souborů Win32 pro čtení nebo zápis dat FILESTREAM BLOB mohou narazit na konfliktní chyby s příkazy Transact-SQL, které jsou spravovány v běžné transakci. To zahrnuje dotazy Transact-SQL nebo MARS, jejichž provedení trvá dlouhou dobu. Aplikace musí být pečlivě navržené tak, aby se těmto typům konfliktů vyhnuly.
Když se databázový stroj NEBO aplikace SQL Serveru pokusí otevřít FILESTREAM BLOBs, databázový stroj zkontroluje přidružený kontext transakce. Databázový stroj povolí nebo odmítne požadavek na základě toho, jestli otevřená operace pracuje s příkazy DDL, příkazy DML, načítáním dat nebo správou transakcí. Následující tabulka ukazuje, jak databázový stroj určuje, zda bude příkaz Transact-SQL povolen nebo odepřen na základě typu souborů, které jsou otevřeny v transakci.
příkazy Transact-SQL | Otevřeno pro čtení | Otevřeno pro zápis |
---|---|---|
Příkazy DDL, které pracují s metadaty databáze, jako jsou CREATE TABLE, CREATE INDEX, DROP TABLE a ALTER TABLE. | Povoleno | Jsou blokovány a selžou s vypršením časového limitu. |
Příkazy DML, které pracují s daty uloženými v databázi, například UPDATE, DELETE a INSERT. | Povoleno | Odmítnuto |
VYBRAT | Povoleno | Povolený |
POTVRZENÍ TRANSAKCE | Odmítnuto | Odmítnuto*. |
ULOŽIT TRANSAKCI | Odmítnuto* | Odmítnuto |
VRÁCENÍ ZPĚT | Povolený* | Povoleno* |
* Transakce je zrušena a otevřené popisovače pro kontext transakce jsou neplatné. Aplikace musí zavřít všechny otevřené popisovače.
Příklady
Následující příklady ukazují, jak Transact-SQL příkazy a přístup FILESTREAM Win32 mohou způsobit konflikty.
A. Otevření objektu BLOB FILESTREAM pro přístup k zápisu
Následující příklad ukazuje účinek otevření souboru pouze pro přístup k zápisu.
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. Otevření objektu BLOB FILESTREAM pro čtení
Následující příklad ukazuje účinek otevření souboru jen pro čtení.
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. Otevírání a zavírání několika souborů FILESTREAM BLOB
Pokud je otevřeno více souborů, použije se nejvíce omezující pravidlo. Následující příklad otevře dva soubory. První soubor se otevře pro čtení a druhý pro zápis. Příkazy DML budou odepřeny, dokud se druhý soubor neotevře.
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. Nedaří se zavřít kurzor
Následující příklad ukazuje, jak neuzavřený kurzor příkazu může zabránit OpenSqlFilestream()
v otevření objektu BLOB pro přístup k zápisu.
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.
Viz také
Přístup k datům FILESTREAM s OpenSqlFilestream
použití více aktivních sad výsledků (MARS)