One possible solution would be to check the value of the min_active_rowversion function:
select ... from [TableName] where [TimeStamp] > @lastTimeStamp and @@dbts < min_active_rowversion();
In this case, in the situation described in the question, after the commit in transaction 2, nothing would be returned (an additional condition would be false , because there is an incomplete rowversion-active transaction 1). Both added rows would be returned after commit in transaction 1. Ie With this modification, "new data" may be delayed.
Fat minus min_active_rowversion is its non-selectivity. This function does not allow to understand if an incomplete transaction works with the table of interest to us, or with some other one, which also has a field of the type timestamp ( rowversion ). Those. There may be situations where the "new data" will not be given on a false basis.
If the application allows for possible data lags (including for false reasons), then an additional check may be the way out.
An alternative would be to use Change Tracking , a built-in functionality for tracking changed data in tables.
When using Change Tracking , unlike rowversion , the increment of the data version occurs not at the moment of execution of the command, but during commit transactions. Information about deleted data rows is also saved, which the rowversion mechanisms do not provide.
To use this functionality, you need to enable the corresponding option on the database:
alter database [DbName] set change_tracking = on;
And on the table itself:
alter table [TableName] enable change_tracking;
By default, data about changes is stored for 2 days and deleted automatically. Database options within certain limits can change the retention period, and auto-deletion can be disabled.
The request for getting new and changed data will look approximately like the following ( change_tracking_min_valid_version for simplicity):
-- это значение передаётся из приложения declare @lastVersion bigint = ... -- это значение будет использоваться как @lastVersion в следующий раз select change_tracking_current_version(); select T.* from [TableName] T join changetable(changes [TableName], @lastVersion) CT on CT.ID = T.ID;
Those. the table is connected by the primary key with the special table function changetable , which is passed the version number obtained in the previous time.
WHERE [TimeStamp]>MaxTimeStamp, where MaxTimeStamp is the maximum of all previousTimeStamp,TimeStampin the program works without explicit transactions - Dmitry Chistikmin_active_rowversion()function, not sure (depends on the application logic). The alternative is to use Change Tracking (an example, if necessary, I will compile). When using Change Tracking, the data version does not increase untilcommit. That is, in this case, transaction 1, despite the fact that it changed the data before transaction 2, and itscommithappened later, would increase the version. - i-one