java - Why do gaps appear in a List backed by @ManyToMany with @OrderColumn -
we have queues of ticket objects persisted database. our entity containing queues looks this:
@entity public class storequeuecollection { @id private int storeid; @manytomany(fetch=fetchtype.lazy) @ordercolumn private list<ticket> mainqueue = new arraylist<ticket>(); @manytomany(fetch=fetchtype.lazy) @ordercolumn private list<ticket> cancelledqueue = new arraylist<ticket>(); .. etc
we have 1 operation moves ticket 1 queue (call changestatus), , adds new ticket end of queue (call newticket).
when 2 operations interleave on same queue, operations work, end "gap" in our queue. in database, looks missing index in order column of table, this: 0, 1, 2, 4. when queue loaded java, missing index becomes null element in queue.
we using pessimistic locking on storequeuecollection object prevent inconsistent interleaved updates, it's not working expect. logging, see strange sequences this:
- changeticketstatus() starts - lock queue using entitymanager.refresh() - ticket x removed front of queue - queue entitymanager.flush()ed * newticket() starts * creates new ticket y, locks storequeuecollection using entitymanager.refresh(); * ticket y added end of queue * ticket y has fields initialized , save()d * call refresh(), method blocked - changeticketstatus() resumes (printing in-memory queue shows ticket x not in queue a) - ticket x added queue b - ticket x has fields modified - ticket x saved using repository.save() (printing in-memory queue shows ticket x not in queue a) - changeticketstatus() completes * newticket() resumes * refresh() returns (printing in-memory queue shows ticket x still in queue!) * ticket y added end of queue (printing in-memory queue shows ticket x , y in queue) * queues save()d
all locks lockmodetype.pessimistic_write , scope pessimisticlockscope.extended.
after sequence of execution, assertion triggers thread checks null entries in queue. mysteriously, queue correct (x deleted, y added end), there gap in order column before y.
any suggestions on we're doing wrong appreciated!
are locking single rows, or of threads locking common 'queue' row? if latter, keep in mind need maintain transaction entire time want lock held. if former, locking single (different) rows won't prevent interleaving operations.
you didn't mention backend you're using, database logging tools (like sql server's profiler , activity monitor) can helpful determining going on, since can ordered list of sql statements issued database.
Comments
Post a Comment