I want to lookup a primary key from a table given some criteria, and if there is no match insert a new row and return the new key. For example, there is a USER table with 3 columns (ID, FIRST_NAME, LAST_NAME), where ID is the identity column, and a unique index exists on the other two columns.
Service layer:
DAO layer:Code:// this method can be potentially executed by multiple threads @Transactional int getId(String firstName, String lastName) { try { id = personDao.getId(firstName, lastName); } catch (EmptyResultDataAccessException e) { // no match - try to insert try { id = personDao.insert(firstName, lastName); } catch (DuplicateKeyException e2) { // concurrent thread already inserted the row - get existing ID id = personDao.getId(firstName, lastName); } } return id; }
Is the above design correct (let's assume that a stored procedure that would provide similar functionality is not available)?Code:@Cacheable("personIds") int getId(String firstName, String lastName) { // lookup and return ID ... } @CachePut("personIds") int insert(String firstName, String lastName) { // insert and return the new ID ... }
Are there any special considerations regarding the isolation level?
Is Spring cache abstraction (@Cacheable, @CachePut above) thread-safe (regardless of the underlying caching provider, i.e. EHCache, Coherence, etc.) or relevant methods need to be synchronized?
Thanks,
Lukasz


Reply With Quote