/** * Makes insert of last value of identifier * * @param connection * @param value * @throws SQLException */ private void insert(Connection connection, IntegralDataTypeHolder value) throws SQLException { PreparedStatement insertPS = null; try { statementLogger.logStatement(insertQuery, FormatStyle.BASIC.getFormatter()); insertPS = connection.prepareStatement(insertQuery); insertPS.setString(FIRST_COLUMN, segmentValue); value.bind(insertPS, SECOND_COLUMN); insertPS.execute(); } finally { close(insertPS); } }
private void onSelect(Connection connection, IntegralDataTypeHolder value) throws SQLException { PreparedStatement selectPS = connection .prepareStatement(selectQuery); try { selectPS.setString(FIRST_COLUMN, segmentValue); ResultSet selectRS = selectPS.executeQuery(); if (selectRS.next()) { value.initialize(selectRS, FIRST_COLUMN); } else { value.initialize(currentValue); insert(connection, value); } selectRS.close(); } catch (SQLException ex) { LOG.unableToReadOrInitHiValue(ex); throw ex; } finally { selectPS.close(); } }
@Override public IntegralDataTypeHolder execute(Connection connection) throws SQLException { IntegralDataTypeHolder value = IdentifierGeneratorHelper .getIntegralDataTypeHolder(identifierType .getReturnedClass()); int rows; do { statementLogger.logStatement(selectQuery, FormatStyle.BASIC.getFormatter()); onSelect(connection, value); statementLogger.logStatement(updateQuery, FormatStyle.BASIC.getFormatter()); rows = onUpdate(connection, value); } while (rows == ZERO_ROWS); return value; }
@Override public Serializable generate(AccessCallback callback) { // IMPL NOTE : this method is called concurrently and is // not synchronized. It is very important to work on the // local variable: the field lastSourceValue is not // reliable as it might be mutated by multipled threads. // The lastSourceValue field is only accessed by tests, // so this is not a concern. IntegralDataTypeHolder value = null; while ( value == null || value.lt( 1 ) ) { value = callback.getNextValue(); } lastSourceValue = value; return value.makeValue(); }
@Override public IntegralDataTypeHolder getNextValue() { ReturningWork returnWork = new ReturningWork(statementLogger, currentValue); return session.getTransactionCoordinator().getTransaction() .createIsolationDelegate() .delegateWork(returnWork, Boolean.TRUE); }
@Override public IntegralDataTypeHolder getLastSourceValue() { return noTenantGenerationState().lastSourceValue; }
@Override public synchronized IntegralDataTypeHolder getLastSourceValue() { return noTenantGenerationState().lastSourceValue.copy(); }
private IntegralDataTypeHolder makeValue() { return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() ); }
@Override public IntegralDataTypeHolder getLastSourceValue() { return lastSourceValue; }
private IntegralDataTypeHolder makeValue() { return IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); }
@Override public AccessCallback buildCallback(final SessionImplementor session) { final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry() .getService( JdbcServices.class ) .getSqlStatementLogger(); final SessionEventListenerManager statsCollector = session.getEventListenerManager(); return new AccessCallback() { @Override public IntegralDataTypeHolder getNextValue() { return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( new AbstractReturningWork<IntegralDataTypeHolder>() { @Override public IntegralDataTypeHolder execute(Connection connection) throws SQLException { final IntegralDataTypeHolder value = makeValue(); int rows; do { final PreparedStatement selectStatement = prepareStatement( connection, selectQuery, statementLogger, statsCollector ); try { final ResultSet selectRS = executeQuery( selectStatement, statsCollector ); if ( !selectRS.next() ) { final String err = "could not read a hi value - you need to populate the table: " + tableName; LOG.error( err ); throw new IdentifierGenerationException( err ); } value.initialize( selectRS, 1 ); selectRS.close(); } catch (SQLException sqle) { LOG.error( "could not read a hi value", sqle ); throw sqle; } finally { selectStatement.close(); } final PreparedStatement updatePS = prepareStatement( connection, updateQuery, statementLogger, statsCollector ); try { final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1; final IntegralDataTypeHolder updateValue = value.copy().add( increment ); updateValue.bind( updatePS, 1 ); value.bind( updatePS, 2 ); rows = executeUpdate( updatePS, statsCollector ); } catch (SQLException e) { LOG.unableToUpdateQueryHiValue( tableName, e ); throw e; } finally { updatePS.close(); } } while ( rows == 0 ); accessCounter++; return value; } }, true ); } @Override public String getTenantIdentifier() { return session.getTenantIdentifier(); } }; }
@Override public synchronized IntegralDataTypeHolder getLastSourceValue() { return noTenantGenerationState().lastSourceValue; }
@Override public IntegralDataTypeHolder getLastSourceValue() { return noTenantGenerationState().hiValue; }
@Override public AccessCallback buildCallback(final SessionImplementor session) { return new AccessCallback() { @Override public IntegralDataTypeHolder getNextValue() { accessCounter++; try { final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { rs.next(); final IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); value.initialize( rs, 1 ); if ( LOG.isDebugEnabled() ) { LOG.debugf( "Sequence value obtained: %s", value.makeValue() ); } return value; } finally { try { session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } catch( Throwable ignore ) { // intentionally empty } } } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle) { throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not get next sequence value", sql ); } } @Override public String getTenantIdentifier() { return session.getTenantIdentifier(); } }; }
@Override public void nextValue(RowKey key, IntegralDataTypeHolder value, int increment, int initialValue) { throw new NotImplementedException("구현 중"); }
@Override public void nextValue(RowKey key, IntegralDataTypeHolder value, int increment, int initialValue) { //To change body of implemented methods use File | Settings | File Templates. }
private int onUpdate(Connection connection, IntegralDataTypeHolder value) throws SQLException { int rows; PreparedStatement updatePS = connection .prepareStatement(updateQuery); try { final IntegralDataTypeHolder updateValue = value.copy() .initialize(currentValue); // TODO check for incrementSize // increment options updateValue.increment(); // gets existing value and // incremented current values as // long types to compare Long existing = value.copy().makeValue().longValue(); Long current = updateValue.copy().makeValue().longValue(); // checks if incremented current // value is less then value and // puts incremented value // instead of incremented // current value for // update if (existing > current) { updateValue.initialize(existing).increment(); } updateValue.bind(updatePS, FIRST_COLUMN); value.bind(updatePS, SECOND_COLUMN); updatePS.setString(THIRD_COLUMN, segmentValue); rows = updatePS.executeUpdate(); value.initialize(currentValue); } catch (SQLException ex) { LOG.unableToUpdateQueryHiValue(tableName, ex); throw ex; } finally { updatePS.close(); } return rows; }
/** * Getter for property 'lastValue'. * <p/> * Exposure intended for testing purposes. * * @return Value for property 'lastValue'. */ @SuppressWarnings( {"UnusedDeclaration"}) public synchronized IntegralDataTypeHolder getLastValue() { return noTenantGenerationState().value; }
/** * Retrieve the next value from the underlying source. * * @return The next value. */ public IntegralDataTypeHolder getNextValue();
/** * Getter for property 'lastValue'. * <p/> * Exposure intended for testing purposes. * * @return Value for property 'lastValue'. */ public synchronized IntegralDataTypeHolder getLastValue() { return noTenantGenerationState().value.copy().decrement(); }
/** * Getter for property 'upperLimit'. * <p/> * Exposure intended for testing purposes. * * @return Value for property 'upperLimit'. */ public synchronized IntegralDataTypeHolder getHiValue() { return noTenantGenerationState().upperLimit; }
/** * Getter for property 'lastValue'. * <p/> * Exposure intended for testing purposes. * * @return Value for property 'lastValue'. */ public IntegralDataTypeHolder getLastValue() { return noTenantGenerationState().value.copy().decrement(); }
/** * A common means to access the last value obtained from the underlying * source. This is intended for testing purposes, since accessing the * underlying database source directly is much more difficult. * * @return The last value we obtained from the underlying source; * null indicates we have not yet consulted with the source. */ public IntegralDataTypeHolder getLastSourceValue();