After a rowset's transaction commits or aborts, there are two possibilities: the full functionality of the rowset is preserved or the rowset enters a zombie state. A preserved rowset is an object with all its capabilities intact. A zombie rowset is an object whose functionality is virtually lost. Specifically, zombie rowsets support only IUnknown operations and the release of the outstanding row and accessor handles. All other operations on the rowset produce the error E_UNEXPECTED.
The behavior of a rowset after a commit is determined by the property DBPROP_COMMITPRESERVE. If this property is VARIANT_FALSE, then the rowset enters a zombie state. However, if the property is VARIANT_TRUE, then the rowset remains fully functional after the commit, with all of its rows, bookmarks, pending changes, and so on still valid.
Similarly, the behavior of a rowset on an abort is determined by the property DBPROP_ABORTPRESERVE. If the property is VARIANT_FALSE, rowsets created with the aborting transaction enter zombie states after an abort. If the property is VARIANT_TRUE, the rowset remains fully functional, with all of its rows, bookmarks, pending changes, and so on still valid. However, all changes made visible to the data source within the aborted transaction are undone.
Preserved rowsets never automatically synchronize with the data source. For example, if the transaction is aborted and DBPROP_ABORTPRESERVE is VARIANT_TRUE, then changes undone in the data source are not undone in the rowset. In delayed update mode, any pending changes are not undone in the rowset. The consumer must call IRowsetRefresh::RefreshVisibleData to synchronize the rowset with the data source.
Even if a rowset is created with preserving properties, it may enter a zombie state if other objects on which it depends are destroyed as the result of an abort. For example, a rowset may enter a zombie state if a table on which it was built was created as part of the same transaction that was aborted.