IRowsetRefresh::RefreshVisibleData

Retrieves the data values from the data store that are visible to the transaction for the specified rows.

Syntax

HRESULT RefreshVisibleData (
   HCHAPTER         hChapter,
   DBCOUNTITEM      cRows,
   const HROW       rghRows[],
   BOOL             fOverwrite,
   DBCOUNTITEM     *pcRowsRefreshed,
   HROW           **prghRowsRefreshed,
   DBROWSTATUS    **prgRowStatus);

Parameters

  • hChapter
    [in] The chapter handle designating the rows to refresh. For nonchaptered rowsets, the caller must set hChapter to DB_NULL_HCHAPTER. For chaptered rowsets, DB_NULL_HCHAPTER designates the entire rowset.

  • cRows
    [in] The count of rows to refresh. If cRows is zero, IRowsetRefresh::RefreshVisibleData ignores rghRows and reads in current values for all active rows.

  • rghRows
    [in] An array of cRows row handles to be refreshed. If cRows is zero, this argument is ignored.

  • fOverwrite
    [in] TRUE if the provider should discard any pending changes to a given row and accept the visible values as the new current values; FALSE otherwise.

  • pcRowsRefreshed
    [out] A pointer to memory in which to return the number of rows the method attempted to refresh. This is still the case if DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED is returned. If any other error occurs, the provider sets *pcRowsRefreshed to zero. If this is a null pointer, no count of rows is returned.

  • prghRowsRefreshed
    [out] A pointer to memory in which to return the array of row handles the method attempted to refresh. If cRows is not zero, the elements of this array are in one-to-one correspondence with those of rghRows. If cRows is zero, the elements of this array are the handles of all rows that have been updated by the operation. In this case, IRowsetRefresh::RefreshVisibleData will add to the reference count of the rows whose handles are returned in prghRowsRefreshed.

    The rowset allocates memory for the handles and the client should release this memory with IMalloc::Free when no longer needed. This argument is ignored if pcRowsRefreshed is a null pointer and must not be a null pointer otherwise. If *pcRowsRefreshed is zero on output or the method fails, the provider does not allocate any memory and ensures that *prghRowsRefreshed is a null pointer on output.

  • prgRowStatus
    [out] A pointer to memory in which to return an array of row status values. The elements of this array correspond one-to-one with the elements of *prghRowsRefreshed. If no errors occur while refreshing a row, the corresponding element of *prgRowStatus is set to DBROWSTATUS_S_OK if the row is successfully resynchronized, or to DBROWSTATUS_S_NOCHANGE if the provider can easily determine that there was no change to the value. If an error occurs while refreshing a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. If prgRowStatus is a null pointer, no row status values are returned.

    The rowset allocates memory for the row status values and returns the address to this memory; the client releases this memory with IMalloc::Free when it is no longer needed. This argument is ignored if pcRowsRefreshed is a null pointer. If *pcRowsRefreshed is zero on output or the method fails, the provider does not allocate any memory and ensures that *prgRowStatus is a null pointer on output.

Return Code

  • S_OK
    The method succeeded. All rows were successfully processed. For each row, prgRowStatus contains one of the following:

    • DBROWSTATUS_S_NOCHANGE if the provider could easily detect that there were no changes made to the data store for this row.

    • DBROWSTATUS_S_OK in all other cases.

  • DB_S_ERRORSOCCURRED
    An error occurred while refreshing a row, but at least one row was successfully refreshed. Successes can occur for the reason listed under S_OK. The following errors can occur:

    • An element of rghRows was invalid. The corresponding element of *prgRowStatus contains DBROWSTATUS_E_INVALID.

    • Refreshing a row was canceled during notification. The row was not refreshed, and the corresponding element of *prgRowStatus contains DBROWSTATUS_E_CANCELED.

    • An element of rghRows referred to a row for which a deletion had been transmitted to the data store. The corresponding element of *prgRowStatus contains DBROWSTATUS_E_DELETED.

    • The row was not refreshed due to reaching a limit on the server, such as a query execution timing out. The error in the corresponding element of *prgRowStatus contains DBROWSTATUS_E_LIMITREACHED.

    • An element of rghRows referred to a row on which a storage object was open. The corresponding element of *prgRowStatus contains DBROWSTATUS_E_OBJECTOPEN.

    • An element of rghRows referred to a pending insert row. The corresponding element of *prgRowStatus contains DBROWSTATUS_E_PENDINGINSERT.

    • DBPROP_STRONGIDENTITY was VARIANT_FALSE, and an element of rghRows referred to a row for which an insertion had been transmitted to the data store. The row was not refreshed, and the corresponding element of *prgRowStatus contains DBROWSTATUS_E_NEWLYINSERTED.

  • E_FAIL
    A provider-specific error occurred.

  • E_INVALIDARG
    cRows was not zero, and rghRows was a null pointer.

    pcRowsRefreshed was not a null pointer, and prghRowsRefreshed was a null pointer.

  • E_UNEXPECTED
    ITransaction::Commit or ITransaction::Abort was called, and the object is in a zombie state.

  • DB_E_ERRORSOCCURRED
    Errors occurred while refreshing all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

  • DB_E_NOTREENTRANT
    The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

  • DB_SEC_E_PERMISSIONDENIED
    The consumer did not have sufficient permission to refresh the rows.

Comments

IRowsetRefresh::RefreshVisibleData retrieves the data values from the data store that are visible to the transaction for the specified rows. Changes made to the row by the current transaction are always visible to IRowsetRefresh::RefreshVisibleData, including changes made by other rowsets in the same transaction. Whether changes made by other transactions are visible to IRowsetRefresh::RefreshVisibleData depends on the isolation level of the current transaction. Therefore, RefreshVisibleData uses values as follows:

  • Read Uncommitted. The changes most recently made, committed or uncommitted, by any transaction are used. If no changes have been made by any transaction, the original row is used.

  • Read Committed. The changes most recently made by the current transaction or committed by other transactions are used. If no changes have been made by the current transaction or committed by other transactions, the original row is used.

  • Repeatable Read and higher. The changes most recently made by the current transaction are used. If no changes have been made by the current transaction, the original row is used.

For providers that keep a local copy of visible data, IRowsetRefresh::RefreshVisibleData updates the provider's local copy of the visible data for any indicated rows with pending changes.

When fOverwrite is TRUE, the provider discards any pending changes to a given row and accepts the visible values as the new current values that will be returned by calling IRowset::GetData or IRowsetUpdate::GetOriginalData. This affects rows with or without pending changes. Any changes already transmitted to the data store are not lost; they will be committed or aborted when the transaction is committed or aborted. But all pending changes are lost because they exist only in the rowset's copy of the row and the fOverwrite TRUE option overwrites the contents of this copy. The pending change status in this case is removed from the row.

When fOverwrite is FALSE, the provider makes no change to the pending status of the row. It does not affect the current values of the row (available through IRowset::GetData) or the original values of the row (available through IRowsetUpdate::GetOriginalData). If the provider keeps a local copy of the visible data values, it refreshes the values for the indicated rows. If the provider does not keep a local copy of the visible data values, the indicated row has no pending changes, or if all columns in the row are deferred, the provider reports success without refreshing any rows.

Providers that perform optimistic updates in a disconnected scenario usually use the cached visible values on a pending row as the source of concurrency conflict detection values. For example, the values used to identify the row to a SQL-based provider through a WHERE clause would come from this buffer. Therefore, refreshing the visible values buffer for a row with pending changes via IRowsetRefresh::RefreshVisibleData potentially affects the behavior of a subsequent call to IRowsetUpdate::Update for that row because it may introduce new acceptable identity values into the conflict-detection mechanism of the provider.

If a specified row has been deleted from the data store and this deletion is visible, IRowsetRefresh::RefreshVisibleData returns DBROWSTATUS_E_DELETED in the error status array for the row. This row is subsequently treated as a deleted row for the purposes of IRowset::GetData (if fOverwrite is TRUE) or for IRowsetRefresh::GetLastVisibleData (if fOverwrite is FALSE).

If the handle of a deleted row has been specified in rghRows, the handle is returned in the prghRowsRefreshed array and the status is set to DBROWSTATUS_E_DELETED.

When cRows is zero, the provider may opt to not return any reference to hard-deleted rows. This is the preferred behavior. However, some providers may return hard-deleted rows, represented in the prghRowsRefreshed array by DB_NULL_HROW and with a status of DBROWSTATUS_E_DELETED.

If IRowsetRefresh::RefreshVisibleData encounters an error while attempting to refresh a row, such as a bad row handle, it notes the error in *prgRowStatus, continues processing, and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Although the rows are refreshed in undefined order, the ordering of *prgRowStatus must match the order of the row handle array so that the consumer can perform a side-by-side scan of each array to determine which rows were not refreshed.

If cRows is zero and pcRowsRefreshed and prghRowsRefreshed are not null pointers, IRowsetRefresh::RefreshVisibleData adds to the reference count of the rows it returns in *prghRowsRefreshed to ensure that the consumer has these row handles.

See Also

Reference

IRowsetRefresh::GetLastVisibleData