Hi.
I've implemented a queue component that can take actions and execute them in the order they were put into the queue. Each action has an id using the "sequence" hibernate generator class:
Code:
<id name="id" type="java.lang.Long" column="id">
<generator class="sequence">
<param name="sequence">rb_action_id_seq</param>
</generator>
</id>
All works as expected until multiple threads come into play. Under load it can happen, that a sequence of actions that should normally be inserted "in a row" (for the order I take the id) get interfered by another action that is inserted by another thread. The reason is clear und simple - since "sequence" uses the database sequence (postgresql 8.1 in this case), getting the needed sequence is out of scope of a transaction and so the needed order (id) gets mixed up. Since the component is used in a cluster, a local synchronisation isn't sufficient and must be cluster wide. So my idea is to let the synchronisation take place on database level.
My question is, can hibernate help me with this? Perhaps there exists a sequence generator that is transactional? So inserting for example 3 actions "in a row" will get the sequence numbers in a transaction (other threads have to wait because of that lock) and writes the actions with these ids in one go. That would avoid that other threads get id's between the 3 ones before. I'm aware of the performance decrease because of the locking that would occur, but I don't see any other solution right now.
Any hints/ideas?