Tuesday, December 31, 2013

I have an ordering platform on a remote webserver and a local production machine here at my office. Both webservers access the same remote MySQL (InnoDB) database.
My Problem: The production takes several minutes in which 2-3 transactions are open. In this time I generate new invoice numbers and increment them. The most recent invoice number is saved in a Numbers-Table on the database.
public Long getNewInvoiceNumber() {
    Criteria crit = getSession().createCriteria(Numbers.class);
    Numbers n = ((Numbers)crit.uniqueResult());
    Long newNumber = n.getInvoiceNumber() + 1L;
    n.setInvoiceNumber(newNumber);
    return newNumber;
}
Now when someone is saving a new order during the production they are accessing the same Numbers-Table to generate another number (not the invoice). All the orders processed by the production are saved with the correct invoice numbers. However, the Numbers-Table isn't updated with the newest value and the invoice number remains the same as before the production.
I understand that one of the transaction gets a "stale table" message. But what is the behavior of MySQL / Hibernate / Java? I'd like to get an exception from one of the transactions so I can rollback and don't have this dangerous database inconsistency.
EDIT : This is how the table Numbers looks like:
id | invoice_number | tag_number
0  | 16533          | 1055
id is the primary key. I only access this one row and increase the needed number.
EDIT 2 : Okey, I see that this table structure is kinda bad. I updated it to:
id             | number
invoice_number | 16533
tag_number     | 1055
Now I can access each row independently. Don't know if that solves my problem though.
share|improve this question
 
Does your Numbers.class table only have 1 row ever? Take a look at the APIs for setLockMode() / setLockOptions(). You need to SELECT ... FOR UPDATE to ensure no other user is doing the same thing. Also you need to getSession().update(n); right ? –  Darryl Miles Sep 20 '12 at 13:10 
 
Yes, as of now there is only 1 row ever. I thought the database has its own automatic locking mode, I wanna know the behavior if there are 2 users changing the row simultaneously. –  rotsch Sep 20 '12 at 13:20
 
Two independent users can view the same or old data at the same time from two different transactions. To stop this in the relatively few cases SELECT ... FOR UPDATE exists. I'd research this topic more and test out the theory with a command line SQL client. –  Darryl Miles Sep 20 '12 at 13:26
add comment

2 Answers

public Long getNewInvoiceNumber() {
    Criteria crit = getSession().createCriteria(Numbers.class);
    crit.setLockMode(LockMode.PESSIMISTIC_WRITE);   // LINE ADDED
    Numbers n = ((Numbers)crit.uniqueResult());
    Long newNumber = n.getInvoiceNumber() + 1L;
    n.setInvoiceNumber(newNumber);
    getSession().update(n);              // LINE ADDED
    return newNumber;
}
You must use InnoDB if using MySQL, you should ensure Hibernate is adding the "FOR UPDATE" to the SQL generated for the crit.uniqueResult() part. I would also set a Java breakpoint just after (to stop execution) and manually test the same SQL query causes another client to block.
This is more to test your SQL server is sane and your Dialect is setup correctly and basically the feature works for you.
This forces serialization at the SQL server in the generation of the next InvoiceNumber.
This way you never get 2 InvoiceNumber the same even if 1000 users simultaneously try to make invoices.
NOTE: LockOptions replaces the LockMode to specify mode things about this aspect of concurrency. See the hibernate release notes for help.
NOTE: You talked of transactions lasting minutes. While the transaction is not committed no other user can generate a new invoice number. Maybe you need to run this as a nested and separate transaction. Then you have the problem holes appearing in InvoiceNumber's if there is a failure to use the number due to some other processing error. Accountants / accounting systems don't like holes in invoice numbers, nor them being out of date sequence.
share|improve this answer
add comment
There are different ways to concurrently work with the database, for instance using Optimistic lock or Pessimistic one (you should be careful with the latter since it may cause delays and dead locks).
But I guess in your case you have to change the Numbers table right after some transaction starts, not by the end of it. This would ensure that the slot for the invoice is reserved.
Also makes sense to look at the Id Generators of the Hibernate, you can see there different ideas of how to implement value-generating mechanisms.
share|improve this answer
add comment

5 comments:

oakleyses said...

louis vuitton handbags, oakley sunglasses, louboutin, longchamp outlet, nike shoes, louis vuitton outlet stores, chanel handbags, burberry outlet, prada outlet, jordan shoes, tiffany and co, michael kors outlet, tory burch outlet, louis vuitton outlet, longchamp handbags, nike free, true religion jeans, michael kors outlet, kate spade outlet, polo ralph lauren outlet, tiffany and co, prada handbags, polo ralph lauren outlet, michael kors outlet, michael kors outlet, longchamp handbags, oakley sunglasses, ray ban sunglasses, kate spade handbags, burberry outlet, louis vuitton outlet, louboutin outlet, louboutin, coach factory outlet, air max, air max, coach outlet, gucci outlet, christian louboutin shoes, michael kors outlet, coach purses, ray ban sunglasses, michael kors outlet, louis vuitton, coach outlet store online, true religion jeans, oakley sunglasses cheap

oakleyses said...

ralph lauren, lululemon, air max, hollister, north face, nike air max, polo lacoste, vanessa bruno, timberland, vans pas cher, louboutin, louis vuitton, oakley pas cher, air max pas cher, nike roshe run, air max, true religion outlet, barbour, sac longchamp, air force, hollister, sac louis vuitton, nike free, polo ralph lauren, nike trainers, louis vuitton uk, nike roshe, sac hermes, longchamp, michael kors, sac burberry, sac guess, mulberry, new balance pas cher, converse pas cher, sac louis vuitton, hogan outlet, nike tn, north face, true religion outlet, ray ban pas cher, michael kors, air jordan, nike blazer, nike free pas cher, michael kors pas cher, abercrombie and fitch, ray ban sunglasses

oakleyses said...

mac cosmetics, mont blanc, marc jacobs, canada goose outlet, nike huarache, vans shoes, soccer jerseys, hollister, giuseppe zanotti, beats by dre, abercrombie and fitch, longchamp, insanity workout, celine handbags, bottega veneta, ghd, nfl jerseys, north face outlet, chi flat iron, ugg boots, birkin bag, ugg australia, canada goose, herve leger, ugg pas cher, rolex watches, valentino shoes, canada goose uk, canada goose, ferragamo shoes, canada goose, ugg boots, uggs outlet, north face jackets, soccer shoes, asics running shoes, new balance shoes, p90x, lululemon outlet, canada goose jackets, mcm handbags, instyler, babyliss pro, ugg, wedding dresses, jimmy choo outlet, reebok outlet, nike roshe run

oakleyses said...

parajumpers, karen millen, air max, converse, pandora charms, moncler, louboutin, moncler, links of london, lancel, juicy couture outlet, oakley, hollister, pandora charms, supra shoes, thomas sabo, canada goose, gucci, wedding dresses, timberland boots, swarovski crystal, air max, coach outlet store online, moncler, ray ban, canada goose, moncler, ugg, louis vuitton, swarovski, hollister, montre homme, moncler, hollister clothing store, ralph lauren, rolex watches, moncler outlet, moncler, iphone 6 cases, baseball bats, juicy couture outlet, toms shoes, vans, pandora jewelry, ugg, converse shoes

Zheng junxai5 said...

zhengjx20160721
jordan 3 powder blue
coach outlet store online clearances
toms wedges
louis vuitton purses
coach outlet
cheap jordans
retro 11
oakley outlet
nike free 5.0
coach factory outlet
louis vuitton purses
gucci handbags
louis vuitton outlet online
adidas superstar trainers
louis vuitton handbags
coach outlet online
michael kors outlet
louis vuitton outlet
ralph lauren sale
michael kors purses
michael kors outlet
cheap toms shoes
nfl jerseys
cheap toms
ray ban sunglasses uk
louboutin femme
michael kors handbags
coach outlet store online
coach factory outlet
louis vuitton purses
nike sb dunks
nike blazers uk
coach outlet store
nike air max uk
nike uk
polo shirts
gucci bags
adidas running shoes
true religion outlet online
michael kors handbags