15

Could someone help me find the equivalent of Timestamp/Rowversion (SQL Server) with PostgreSQL?

I'm using NHibernate on Mono (UNIX).

I think that Timestamp (PostgreSQL) is the equivalent of Datetime (SQL Server) - it's not what I'm looking for.

Edit 1: For those who don't know what is a Timestamp/Rowversion in SQL Server: http://msdn.microsoft.com/en-us/library/ms182776.aspx (It is mostly used for optimistic concurrency)

4
  • Hi W3Max. You may want to take a look at stackoverflow.com/questions/1035980/… (although it's not specific to NHibernate). Commented Nov 14, 2009 at 19:01
  • It would help if you'd say what is "Timestamp/Rowversion" - I, for one, have absolutely no idea if these are datatypes (what range/precision then?) or some specific "functions" (like rownum in Oracle), or magical stuff that makes your eyebrows to grow. Commented Nov 15, 2009 at 13:08
  • 4
    The OP's rowversion is a value that is "stamped" onto the row automatically by the database engine whenever the row changes. One can use this value to implement optimistic concurrency -- you read the row in, and when you update the row, your update command has a where-condition: where rowversion = theRowVersionReadEarlier. Only if the row has not changed since you read it in will the update take effect. Commented Jan 23, 2013 at 17:19
  • Yea - timestamp in MS SQL Server is not a timestamp at all! The mind boggles. No wonder it's been deprecated. If only MS could "stamp" out the type of thinking from their organisation that got that into their product in the first place, I'm sure a lot of other problems would also disappear. Commented Oct 13, 2021 at 10:18

4 Answers 4

10

See the system columns section in PostgreSQL documentation. In particular, xmin might be what you're looking for.

But be careful using any system columns. They are by definition implementation specific and the details of some of them might change with future versions.

Sign up to request clarification or add additional context in comments.

5 Comments

xmin can be the same for multiple records if they were inserted in one transaction for example.
xmin would be great except it's 32-bit and subject to vacuuming (read non-permanent).
@dev what are the consequences of vacuuming for xmin when used for optimistic locking? Could you elaborate on this, please? As far as I know, npgsql is using xmin for optimistic locking, see npgsql.org/efcore/modeling/concurrency.html.
@dev @Joerg this is confusing to me too. I did some research, and the closest reference to non-permanence that I've found refers to dead tuples (with their associated xmin values) being removed on vacuum. Freezing seems to set relfrozenxid but current and subsequent xmin values appear to be consistent. The biggest concerns to me seem to be the tight coupling to the transaction management system as well as possible collisions due to Transaction ID Wraparound.
@dev may have been referring to the behavior in versions of Postgres before 9.4, where the xmin value would be overwritten by FrozenTransactionId during VACUUM FREEZE. This appears to no longer be the case as of version 9.4. See the "Note" section here: postgresql.org/docs/9.4/…
1

You can create it manually:

  1. Create sequence
  2. Create trigger for insert and update for each table that contains rowversion column
  3. Set rowversion column from sequence

Comments

0

The key thing being missed is that rowversion type changed each time there is an update to the row, even if the net result is that, the row is not changed.

CREATE TABLE MyTest (myKey int PRIMARY KEY  
    ,myValue int, RV rowversion);  
GO   
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);  
GO   
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);  
GO  

select * from MyTest
Go

update MyTest set myValue = 0 
go

/* row version will have changed */
select * from MyTest
Go

The only choice I have found is to create an update trigger.

Comments

-6

If I understand correctly rowversion is the same as serial? If not - you'd have to make your own with triggers.

2 Comments

MSSQL provides function MIN_ACTIVE_ROWVERSION to work with rowversion (msdn.microsoft.com/en-us/library/bb839514.aspx) that is crucial for implementing synchronization-related systems. It seems Postgres does not.
@mtomy it's not, in fact rowversion can't be used for syncing at all. The only guarantee rowversion gives is that for a single row, any changes will modify it. The system is free to generate those numbers as it sees fit, in batches, with gaps, with different cores using a different pool of batched numbers, resulting in seemingly out-of-order values. Syncing versions are provided by change tracking functions, provided change tracking is enabled for a table

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.