Order of revision number in Envers


#1

Hi @Naros,
I understand that Envers using sequence for revision number generation.
How Envers is ensuring the order of revision number generated in a multi thread/multi node environment?

Thanks.


#2

Just like any other sequence-based entity? :wink:

The default configuration for the revision-number sequence is to basically tell ORM to build a sequence called REVISION_GENERATOR in a table called REVISION_GENERATOR and that the sequence starts with the value 1 and should be incremented by 1 for each insert.

So if you have two nodes or threads that are generating changes against an audited entity, the node that creates and persist the revision-entity first gets a revision-number higher than the one that does so afterward.

So the next obvious question is what creates the revision-entity instance.

This is an operation that is typically delayed as late as possible inside the transaction boundary. The way Envers operates, we capture the entity changes mid-transaction when the persistence operation occurs. This means when you call persist, merge, or remove; we examine the entity state and build a list of changes that were affected by that persistence operation; however, all we build is the list of changes and nothing else.

When the transaction is being committed, Hibernate flushes its internal action queue. This flush step basically synchronizes the state of the persistence context with the datastore. Just before Hibernate calls commit on that transaction, it invokes a callback that allows interested registered parties to perform last minute operations just before commit; this is where Envers again comes into play.

It’s here during the BeforeTransactionCompletionProcess that Envers actually constructs the revision-entity instance, asks Hibernate ORM for the next sequence value, injects the sequence value and persists the revision-entity followed by all the audit changes.

So in short; its really no different than maintaining order of a sequence-based entity which you insert in two differing transactions; whether those two transactions are from two differing nodes of your application or from two threads but differing sessions within the same application instance is irrelevant.

Hope that helps answer your question.