Share via


開放式並行存取

開放式同步存取 的名稱衍生自交易之間很少發生衝突的開放式假設;當另一個交易在目前交易讀取資料列的時間,以及更新或刪除資料列的時間之間,更新或刪除該資料列時,即表示發生衝突。 它與封閉式並行存取或鎖定相反,應用程式開發人員認為在封閉式並行存取或鎖定中這類衝突相當常見。

在開放式同步存取中,資料列會保持解除鎖定,直到須加以更新或刪除為止。 此時,便會重新讀取及檢查資料列,確認自上次讀取以來是否已變更。 如果資料列已變更,則會導致更新或刪除失敗,且必須再次嘗試。

若要判斷資料列是否已變更,系統會針對資料列的快取版本檢查其新版本。 這項檢查會基於資料列版本,例如 SQL Server 中的時間戳記資料行,或資料列中各資料行的值。 許多 DBMS 都不支援資料列版本。

開放式同步存取可由資料來源或應用程式實作。 在任何一種情況下,應用程式都應該使用較低的交易隔離等級,例如讀取認可;使用較高層級會否定使用開放式同步存取所獲得的同步存取提升。

如果資料來源實作開放式同步存取,應用程式會將 SQL_ATTR_CONCURRENCY 陳述式屬性設定為 SQL_CONCUR_ROWVER 或 SQL_CONCUR_VALUES。 若要更新或刪除資料列,則會執行定點更新或 Delete 陳述式,或呼叫 SQLSetPos,就像使用封閉式並行存取一樣;如果更新或刪除因衝突發生而失敗,驅動程式或資料來源則會傳回 SQLSTATE 01001 (資料指標作業衝突)。

如果應用程式本身實作開放式同步存取,則會將 SQL_ATTR_CONCURRENCY 陳述式屬性設定為 SQL_CONCUR_READ_ONLY 以便讀取資料列。 如果它會比較資料列版本,且不知道資料列版本資料行,則會使用 SQL_ROWVER 選項呼叫 SQLSpecialColumns,藉此確定此資料行的名稱。

應用程式會藉由將並行存取增加至 SQL_CONCUR_LOCK (以取得資料列的寫入權限),並使用 WHERE 子句執行 UPDATEDELETE 陳述式來更新或刪除資料列,該 WHERE 子句指定應用程式讀取資料列時所使用的版本或值。 如果自那時起資料列已變更,則會導致陳述式失敗。 如果 WHERE 子句無法唯一識別資料列,陳述式可能也會更新或刪除其他資料列;資料列版本一律會唯一識別資料列,但僅限於資料列包含主索引鍵時,資料列值才會唯一識別資料列。