I know one is supposed to use a database sequence to obtain the value for the next key on a table (let’s assume a single-column numeric Primary Key), but in case a sequence is not used, do you see any obvious code smells with the following code (code is in Java for JPA but the pattern is really language and technology independent):
boolean haveSucceeded = false;
int _i = 0 ;
while ((!haveSucceeded) && (_i++ < MAX_RETRIES)) {
try {
user.setId(getFacade().maxId()+1); // line A
getFacade().create(user); // line B
haveSucceeded = true;
} catch (javax.ejb.EJBTransactionRolledbackException exc) {
debug("ConstraintValidationException, "+ ( (_i<MAX_RETRIES)?"retrying":"giving up"));
}
}
Where the retries are happening to account for possible clashes due to concurrent accesses (possibly from other application instances as well) and since it cannot be guaranteed that line A (where the max is calculated) and line B (where the row is inserted) will operate on the same data.
This doesn’t look thread safe.
You should, in a thread-safe way:
This approximates what happens in the database with an autoincrement.
If you can’t lock the table, synchronize the method, either making it
static synchronizedor using astaticlock object, eg:If you have multiple instances of your server running, this approach won’t be enough.