SequencingCallbackImpl getCallbackImpl(AbstractSession writeSession, Accessor accessor) { SequencingCallbackImpl seqCallbackImpl; if (writeSession.hasExternalTransactionController()) { // note that controller obtained from writeSession (not from ownerSession) - // the difference is important in case of ownerSession being a member of SessionBroker: // in that case only writeSession (which is either ClientSession or DatabaseSession) always // has // the correct controller. seqCallbackImpl = (SequencingCallbackImpl) writeSession .getExternalTransactionController() .getActiveSequencingCallback(getOwnerSession(), getSequencingCallbackFactory()); } else { seqCallbackImpl = (SequencingCallbackImpl) accessor.getSequencingCallback(getSequencingCallbackFactory()); } return seqCallbackImpl; }
public Object getNextValue(Sequence sequence, AbstractSession writeSession) { String seqName = sequence.getName(); if (sequence.getPreallocationSize() > 1) { Queue sequencesForName = getPreallocationHandler().getPreallocated(seqName); // First try to get the next sequence value without locking. Object sequenceValue = sequencesForName.poll(); if (sequenceValue != null) { return sequenceValue; } // Sequences are empty, so must lock and allocate next batch of sequences. acquireLock(seqName); try { sequenceValue = sequencesForName.poll(); if (sequenceValue != null) { return sequenceValue; } // note that accessor.getLogin().shouldUseExternalTransactionController() // should be set to false Accessor accessor = getConnectionHandler().acquireAccessor(); try { accessor.beginTransaction(writeSession); try { Vector sequences = sequence.getGeneratedVector(accessor, writeSession); accessor.commitTransaction(writeSession); // Remove the first value before adding to the global cache to ensure this thread gets // one. sequenceValue = sequences.remove(0); // copy remaining values to global cache. getPreallocationHandler().setPreallocated(seqName, sequences); logDebugPreallocation(seqName, sequenceValue, sequences); } catch (RuntimeException ex) { try { // make sure to rollback the transaction we've begun accessor.rollbackTransaction(writeSession); } catch (Exception rollbackException) { // ignore rollback exception } // don't eat the original exception throw ex; } } finally { getConnectionHandler().releaseAccessor(accessor); } } finally { releaseLock(seqName); } return sequenceValue; } else { // note that accessor.getLogin().shouldUseExternalTransactionController() // should be set to false Accessor accessor = getConnectionHandler().acquireAccessor(); try { accessor.beginTransaction(writeSession); try { // preallocation size is 1 - just return the first (and only) element of the allocated // vector. Object sequenceValue = sequence.getGeneratedVector(accessor, writeSession).firstElement(); accessor.commitTransaction(writeSession); return sequenceValue; } catch (RuntimeException ex) { try { // make sure to rollback the transaction we've begun accessor.rollbackTransaction(writeSession); } catch (Exception rollbackException) { // ignore rollback exception } // don't eat the original exception throw ex; } } finally { getConnectionHandler().releaseAccessor(accessor); } } }