FileDocCategorySizeDatePackage
UpdateLockingStrategy.javaAPI DocHibernate 3.2.54045Thu Feb 23 10:32:48 GMT 2006org.hibernate.dialect.lock

UpdateLockingStrategy

public class UpdateLockingStrategy extends Object implements LockingStrategy
A locking strategy where the locks are obtained through update statements.

This strategy is not valid for read style locks.

since
3.2
author
Steve Ebersole

Fields Summary
private static final Log
log
private final org.hibernate.persister.entity.Lockable
lockable
private final org.hibernate.LockMode
lockMode
private final String
sql
Constructors Summary
public UpdateLockingStrategy(org.hibernate.persister.entity.Lockable lockable, org.hibernate.LockMode lockMode)
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.


	                                       	 
	     
		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();
		}
	
Methods Summary
protected java.lang.StringgenerateLockString()

		SessionFactoryImplementor factory = lockable.getFactory();
		Update update = new Update( factory.getDialect() );
		update.setTableName( lockable.getRootTableName() );
		update.setPrimaryKeyColumnNames( lockable.getRootTableIdentifierColumnNames() );
		update.setVersionColumnName( lockable.getVersionColumnName() );
		update.addColumn( lockable.getVersionColumnName() );
		if ( factory.getSettings().isCommentsEnabled() ) {
			update.setComment( lockMode + " lock " + lockable.getEntityName() );
		}
		return update.toStatementString();
	
protected org.hibernate.LockModegetLockMode()

		return lockMode;
	
public voidlock(java.io.Serializable id, java.lang.Object version, java.lang.Object object, org.hibernate.engine.SessionImplementor session)

see
LockingStrategy#lock

		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 JDBCExceptionHelper.convert(
					session.getFactory().getSQLExceptionConverter(),
			        sqle,
			        "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
			        sql
			);
		}