/** @see LockingStrategy#lock */ public void lock( Serializable id, Object version, Object object, int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException { if (!lockable.isVersioned()) { throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]"); } // todo : should we additionally check the current isolation mode explicitly? SessionFactoryImplementor factory = session.getFactory(); try { PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); try { lockable.getVersionType().nullSafeSet(st, version, 1, session); int offset = 2; lockable.getIdentifierType().nullSafeSet(st, id, offset, session); offset += lockable.getIdentifierType().getColumnSpan(factory); if (lockable.isVersioned()) { lockable.getVersionType().nullSafeSet(st, version, offset, session); } int affected = st.executeUpdate(); if (affected < 0) { factory.getStatisticsImplementor().optimisticFailure(lockable.getEntityName()); throw new StaleObjectStateException(lockable.getEntityName(), id); } } finally { session.getBatcher().closeStatement(st); } } catch (SQLException sqle) { throw session .getFactory() .getSQLExceptionHelper() .convert( sqle, "could not lock: " + MessageHelper.infoString(lockable, id, session.getFactory()), sql); } }
/** * Construct a locking strategy based on SQL UPDATE statements. * * @param lockable The metadata for the entity to be locked. * @param lockMode Indictates the type of lock to be acquired. Note that read-locks are not valid * for this strategy. */ public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) { this.lockable = lockable; this.lockMode = lockMode; if (lockMode.lessThan(LockMode.UPGRADE)) { throw new HibernateException("[" + lockMode + "] not valid for update statement"); } if (!lockable.isVersioned()) { log.warn( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]"); this.sql = null; } else { this.sql = generateLockString(); } }
protected String generateLockString() { SessionFactoryImplementor factory = lockable.getFactory(); SimpleSelect select = new SimpleSelect(factory.getDialect()) .setLockMode(lockMode) .setTableName(lockable.getRootTableName()) .addColumn(lockable.getRootTableIdentifierColumnNames()[0]) .addCondition(lockable.getRootTableIdentifierColumnNames(), "=?"); if (lockable.isVersioned()) { select.addCondition(lockable.getVersionColumnName(), "=?"); } if (factory.getSettings().isCommentsEnabled()) { select.setComment(lockMode + " lock " + lockable.getEntityName()); } return select.toStatementString(); }
@Override public void lock( Serializable id, Object version, Object object, int timeout, SharedSessionContractImplementor session) { if (!lockable.isVersioned()) { throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]"); } final EntityEntry entry = session.getPersistenceContext().getEntry(object); // Register the EntityIncrementVersionProcess action to run just prior to transaction commit. ((EventSource) session) .getActionQueue() .registerProcess(new EntityIncrementVersionProcess(object, entry)); }
/** @see LockingStrategy#lock */ public void lock(Serializable id, Object version, Object object, SessionImplementor session) throws StaleObjectStateException, JDBCException { SessionFactoryImplementor factory = session.getFactory(); try { PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); try { lockable.getIdentifierType().nullSafeSet(st, id, 1, session); if (lockable.isVersioned()) { lockable .getVersionType() .nullSafeSet( st, version, lockable.getIdentifierType().getColumnSpan(factory) + 1, session); } ResultSet rs = st.executeQuery(); try { if (!rs.next()) { if (factory.getStatistics().isStatisticsEnabled()) { factory.getStatisticsImplementor().optimisticFailure(lockable.getEntityName()); } throw new StaleObjectStateException(lockable.getEntityName(), id); } } finally { rs.close(); } } finally { session.getBatcher().closeStatement(st); } } catch (SQLException sqle) { throw JDBCExceptionHelper.convert( session.getFactory().getSQLExceptionConverter(), sqle, "could not lock: " + MessageHelper.infoString(lockable, id, session.getFactory()), sql); } }