I must be missing something - I don't see how transaction isolation will solve this problem. For example:
Thread A: Begin transaction Thread B: Begin transaction Thread A: Get last invoice number (10000) Thread B: Get last invoice number (10000) Thread A: Increment invoice number (10001) Thread B: Increment invoice number (10001) Thread A: Store new invoice number Thread B: Store new invoice number Thread A: Commit transaction Thread B: Commit transaction That last step is going to fail no matter how you have your transaction isolation set up. A single-server setup could solve the problem by putting the invoice number generation code inside a synchronized method. In a multi-server setup, you would have to have a test-and-retry method like you suggested. -Adrian --- On Wed, 5/19/10, David E Jones <[email protected]> wrote: > From: David E Jones <[email protected]> > Subject: Re: QuoteId and OrderId sequence, possible race condition? > To: [email protected] > Date: Wednesday, May 19, 2010, 5:32 PM > > It would be nice if it were that easy, but not only could > there be multiple threads in a single app server instance > but there could be multiple app servers using this at the > same time. > > This sounds like a transaction isolation problem, and > really database transaction isolation is the only way to > properly handle this. > > The place to look for this problem in a production system > is what the database tx isolation is set to, and check if it > is handling this right. > > Without handling it through the db the best option would be > to write recovery code, ie call the save invoice in its own > transaction and if it returns an error (and rolls back as > part of that) then increment the ID (as James is doing > manually) and try again. > > -David > > > On May 19, 2010, at 4:42 PM, Adrian Crum wrote: > > > That looks like a bad design. There is no > synchronization, so multiple threads can create invoices > with the same number. > > > > I would recommend creating a Jira issue. > > > > -Adrian > > > > On 5/19/2010 3:30 PM, James McGill wrote: > >> This happened again, this time with an > InvoiceId. > >> > >> What could possibly cause an Invoice to be written > with an InvoiceId > >> (received via, > InvoiceServices.xml#getNextInvoiceId) > >> without getNextInvoiceId writing the incremented > value to > >> PartyAcctgPreference ? > >> > >> In my log I can see the last time an InvoiceId was > created. > >> getNextInvoiceId logs its context, and the method > succeeds (We are using > >> INVSQ_ENF_SEQ etc.). The invoice is created > and everything seems fine. > >> > >> Then the next and subsequent invoices fail because > the PartyAcctgPreference > >> wasn't updated. I can't understand from the > code how that is even possible. > >> > >> Could<store-value > value-field="partyAcctgPreference"/> > >> possibly not be writing, but also not throwing an > error? > >> > >
