Reference Counting of Row Handles

Row handles are of type HROW and are not COM objects. Nevertheless, each row handle has its own associated reference count. These reference counts are incremented by calling IRowset::AddRefRows and decremented by calling IRowset::ReleaseRows. All methods that fetch rows are required to increment the reference counts on the returned row handles. The provider holds the rows until the consumer releases them with IRowset::ReleaseRows. The consumer must call ReleaseRows on a row once for each time it was fetched and each time AddRefRows was called on it.

Rows held by the provider are freed after the rowset's final reference has been released or after all references on the row handle have been freed. Deleting a row does not release the row handle. It does not matter whether the row is deleted by calling IRowsetUpdate::Update on a row with a pending deletion, calling IRowsetUpdate::Undo on a row with a pending insert, or calling IRowsetChange::DeleteRows: The consumer must call IRowset::ReleaseRows to release the row.

Reusing a released row or accessor handle is a programming error and likely to produce unpredictable results, including abnormal program termination. If possible, providers are encouraged to detect released row or accessor handles and return DB_E_BADROWHANDLE or DB_E_BADACCESSOR.

The consumer may need to call IRowset::ReleaseRows for each time a row was referenced in order to release the row within the context of the rowset, to free resources, or to allow additional rows to be fetched if DBPROP_MAXOPENROWS has been reached or DBPROP_CANHOLDROWS is false. However, when the final release is called on a rowset, the provider frees any outstanding referenced row handles. This means that providers should not leak row handles when rowsets are released.