HHH-6865 - PessimisticLockException should be thrown when pessimistic read and write locking strategies fail
This commit is contained in:
parent
3577cbde08
commit
eb59e81bb9
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2009-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,33 +20,20 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate;
|
||||
|
||||
import org.hibernate.dialect.lock.OptimisticEntityLockException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Throw when an optimistic locking conflict occurs.
|
||||
*
|
||||
* @author Scott Marlow
|
||||
*
|
||||
* @deprecated Use {@link org.hibernate.dialect.lock.OptimisticEntityLockException} instead
|
||||
*/
|
||||
public class OptimisticLockException extends HibernateException {
|
||||
|
||||
Object entity;
|
||||
|
||||
public OptimisticLockException(String s) {
|
||||
super(s);
|
||||
public class OptimisticLockException extends OptimisticEntityLockException {
|
||||
public OptimisticLockException(Object entity, String message) {
|
||||
super( entity, message );
|
||||
}
|
||||
|
||||
public OptimisticLockException(String s, Object entity) {
|
||||
super(s);
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Object getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2009-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,39 +20,18 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Thrown when a pessimistic locking conflict occurs.
|
||||
*
|
||||
* @author Scott Marlow
|
||||
*/
|
||||
public class PessimisticLockException extends JDBCException {
|
||||
|
||||
Object entity;
|
||||
|
||||
|
||||
public PessimisticLockException(String s, JDBCException je, Object entity) {
|
||||
super(s, je.getSQLException());
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public PessimisticLockException(String s, SQLException se, Object entity) {
|
||||
super(s, se);
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public PessimisticLockException(String s, SQLException se, String sql) {
|
||||
super(s, se, sql);
|
||||
this.entity = null;
|
||||
}
|
||||
|
||||
public Object getEntity() {
|
||||
return entity;
|
||||
super( s, se, sql );
|
||||
}
|
||||
|
||||
}
|
|
@ -52,6 +52,7 @@ public class EntityVerifyVersionProcess implements BeforeTransactionCompletionPr
|
|||
Object latestVersion = persister.getCurrentVersion( entry.getId(), session );
|
||||
if ( !entry.getVersion().equals( latestVersion ) ) {
|
||||
throw new OptimisticLockException(
|
||||
object,
|
||||
"Newer version [" + latestVersion +
|
||||
"] of entity [" + MessageHelper.infoString( entry.getEntityName(), entry.getId() ) +
|
||||
"] found in database"
|
||||
|
|
|
@ -51,10 +51,10 @@ public interface LockingStrategy {
|
|||
* @param object The object logically being locked (currently not used)
|
||||
* @param timeout timeout in milliseconds, 0 = no wait, -1 = wait indefinitely
|
||||
* @param session The session from which the lock request originated
|
||||
* @throws StaleObjectStateException Indicates an optimistic lock failure
|
||||
* as part of acquiring the requested database lock.
|
||||
* @throws JDBCException Indicates errors from the <tt>JDBC</tt> driver.
|
||||
* @throws StaleObjectStateException Indicates an inability to locate the database row as part of acquiring
|
||||
* the requested lock.
|
||||
* @throws LockingStrategyException Indicates a failure in the lock attempt
|
||||
*/
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session)
|
||||
throws StaleObjectStateException, JDBCException;
|
||||
throws StaleObjectStateException, LockingStrategyException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Represents an error trying to apply a {@link LockingStrategy} to an entity
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class LockingStrategyException extends HibernateException {
|
||||
private final Object entity;
|
||||
|
||||
public LockingStrategyException(Object entity, String message) {
|
||||
super( message );
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public LockingStrategyException(Object entity, String message, Throwable root) {
|
||||
super( message, root );
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Object getEntity() {
|
||||
return entity;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
/**
|
||||
* Represents an error trying to apply an optimistic {@link LockingStrategy} to an entity
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class OptimisticEntityLockException extends LockingStrategyException {
|
||||
public OptimisticEntityLockException(Object entity, String message) {
|
||||
super( entity, message );
|
||||
}
|
||||
|
||||
public OptimisticEntityLockException(Object entity, String message, Throwable root) {
|
||||
super( entity, message, root );
|
||||
}
|
||||
}
|
|
@ -22,12 +22,11 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.action.internal.EntityIncrementVersionProcess;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -61,14 +60,8 @@ public class OptimisticForceIncrementLockingStrategy implements LockingStrategy
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -40,9 +41,8 @@ import org.hibernate.persister.entity.Lockable;
|
|||
* <p/>
|
||||
* This strategy is valid for LockMode.OPTIMISTIC
|
||||
*
|
||||
* @since 3.5
|
||||
*
|
||||
* @author Scott Marlow
|
||||
* @since 3.5
|
||||
*/
|
||||
public class OptimisticLockingStrategy implements LockingStrategy {
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class OptimisticLockingStrategy implements LockingStrategy {
|
|||
* Construct locking strategy.
|
||||
*
|
||||
* @param lockable The metadata for the entity to be locked.
|
||||
* @param lockMode Indictates the type of lock to be acquired.
|
||||
* @param lockMode Indicates the type of lock to be acquired.
|
||||
*/
|
||||
public OptimisticLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
this.lockable = lockable;
|
||||
|
@ -63,16 +63,10 @@ public class OptimisticLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.hibernate.dialect.lock.LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new OptimisticLockException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
throw new OptimisticLockException( object, "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
EntityEntry entry = session.getPersistenceContext().getEntry(object);
|
||||
EventSource source = (EventSource)session;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
|
||||
/**
|
||||
* Represents an error trying to apply a pessimistic {@link LockingStrategy} to an entity
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PessimisticEntityLockException extends LockingStrategyException {
|
||||
public PessimisticEntityLockException(Object entity, String message, JDBCException root) {
|
||||
super( entity, message, root );
|
||||
}
|
||||
}
|
|
@ -22,12 +22,11 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -60,15 +59,8 @@ public class PessimisticForceIncrementLockingStrategy implements LockingStrategy
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "[" + lockMode + "] not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -50,8 +51,10 @@ import org.hibernate.sql.SimpleSelect;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Scott Marlow
|
||||
*
|
||||
* @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
|
||||
* @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingStrategy {
|
||||
|
@ -65,56 +68,53 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS
|
|||
super( lockable, lockMode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.hibernate.dialect.lock.LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
getLockable().getVersionType().nullSafeSet(
|
||||
st,
|
||||
version,
|
||||
getLockable().getIdentifierType().getColumnSpan( factory ) + 1,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = st.executeQuery();
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor()
|
||||
.optimisticFailure( getLockable().getEntityName() );
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
getLockable().getVersionType().nullSafeSet(
|
||||
st,
|
||||
version,
|
||||
getLockable().getIdentifierType().getColumnSpan( factory ) + 1,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = st.executeQuery();
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor()
|
||||
.optimisticFailure( getLockable().getEntityName() );
|
||||
}
|
||||
throw new StaleObjectStateException( getLockable().getEntityName(), id );
|
||||
}
|
||||
throw new StaleObjectStateException( getLockable().getEntityName(), id );
|
||||
}
|
||||
finally {
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
rs.close();
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"could not lock: " + MessageHelper.infoString( getLockable(), id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
JDBCException e = session.getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( getLockable(), id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
throw new PessimisticLockException( "could not obtain pessimistic lock", e, object );
|
||||
catch (JDBCException e) {
|
||||
throw new PessimisticEntityLockException( object, "could not obtain pessimistic lock", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
@ -47,15 +48,16 @@ import org.hibernate.sql.Update;
|
|||
*
|
||||
* This class is a clone of UpdateLockingStrategy.
|
||||
*
|
||||
* @since 3.5
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Scott Marlow
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
||||
PessimisticReadUpdateLockingStrategy.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
PessimisticReadUpdateLockingStrategy.class.getName()
|
||||
);
|
||||
|
||||
private final Lockable lockable;
|
||||
private final LockMode lockMode;
|
||||
|
@ -65,7 +67,7 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
* 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
|
||||
* @param lockMode Indicates the type of lock to be acquired. Note that
|
||||
* read-locks are not valid for this strategy.
|
||||
*/
|
||||
public PessimisticReadUpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
|
@ -83,50 +85,48 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.hibernate.dialect.lock.LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
||||
lockable.getIdentifierType().nullSafeSet( st, id, offset, session );
|
||||
offset += lockable.getIdentifierType().getColumnSpan( factory );
|
||||
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 ) { // todo: should this instead check for exactly one row modified?
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
throw new StaleObjectStateException( lockable.getEntityName(), id );
|
||||
}
|
||||
|
||||
if ( lockable.isVersioned() ) {
|
||||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
int affected = st.executeUpdate();
|
||||
if ( affected < 0 ) { // todo: should this instead check for exactly one row modified?
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
throw new StaleObjectStateException( lockable.getEntityName(), id );
|
||||
finally {
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
JDBCException e = session.getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
catch ( SQLException e ) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
throw new PessimisticLockException("could not obtain pessimistic lock", e, object);
|
||||
}
|
||||
}
|
||||
catch (JDBCException e) {
|
||||
throw new PessimisticEntityLockException( object, "could not obtain pessimistic lock", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -48,10 +49,11 @@ import org.hibernate.sql.SimpleSelect;
|
|||
*
|
||||
* This class is a clone of SelectLockingStrategy.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Scott Marlow
|
||||
* @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
|
||||
* @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Scott Marlow
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLockingStrategy {
|
||||
|
@ -65,56 +67,52 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking
|
|||
super( lockable, lockMode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout,
|
||||
SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
final String sql = determineSql( timeout );
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
getLockable().getVersionType().nullSafeSet(
|
||||
st,
|
||||
version,
|
||||
getLockable().getIdentifierType().getColumnSpan( factory ) + 1,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = st.executeQuery();
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor()
|
||||
.optimisticFailure( getLockable().getEntityName() );
|
||||
getLockable().getIdentifierType().nullSafeSet( st, id, 1, session );
|
||||
if ( getLockable().isVersioned() ) {
|
||||
getLockable().getVersionType().nullSafeSet(
|
||||
st,
|
||||
version,
|
||||
getLockable().getIdentifierType().getColumnSpan( factory ) + 1,
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
ResultSet rs = st.executeQuery();
|
||||
try {
|
||||
if ( !rs.next() ) {
|
||||
if ( factory.getStatistics().isStatisticsEnabled() ) {
|
||||
factory.getStatisticsImplementor()
|
||||
.optimisticFailure( getLockable().getEntityName() );
|
||||
}
|
||||
throw new StaleObjectStateException( getLockable().getEntityName(), id );
|
||||
}
|
||||
throw new StaleObjectStateException( getLockable().getEntityName(), id );
|
||||
}
|
||||
finally {
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
rs.close();
|
||||
st.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
st.close();
|
||||
catch ( SQLException e ) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"could not lock: " + MessageHelper.infoString( getLockable(), id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
JDBCException e = session.getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( getLockable(), id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
throw new PessimisticLockException( "could not obtain pessimistic lock", e, object );
|
||||
catch (JDBCException e) {
|
||||
throw new PessimisticEntityLockException( object, "could not obtain pessimistic lock", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
@ -47,15 +48,16 @@ import org.hibernate.sql.Update;
|
|||
*
|
||||
* This class is a clone of UpdateLockingStrategy.
|
||||
*
|
||||
* @since 3.5
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Scott Marlow
|
||||
* @since 3.5
|
||||
*/
|
||||
public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class,
|
||||
PessimisticWriteUpdateLockingStrategy.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
PessimisticWriteUpdateLockingStrategy.class.getName()
|
||||
);
|
||||
|
||||
private final Lockable lockable;
|
||||
private final LockMode lockMode;
|
||||
|
@ -65,8 +67,7 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
* 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.
|
||||
* @param lockMode Indicates the type of lock to be acquired. Note that read-locks are not valid for this strategy.
|
||||
*/
|
||||
public PessimisticWriteUpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
|
||||
this.lockable = lockable;
|
||||
|
@ -83,50 +84,47 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LockingStrategy#lock
|
||||
*/
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
Object object,
|
||||
int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException {
|
||||
@Override
|
||||
public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) {
|
||||
if ( !lockable.isVersioned() ) {
|
||||
throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
|
||||
}
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
try {
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
|
||||
try {
|
||||
lockable.getVersionType().nullSafeSet( st, version, 1, session );
|
||||
int offset = 2;
|
||||
|
||||
lockable.getIdentifierType().nullSafeSet( st, id, offset, session );
|
||||
offset += lockable.getIdentifierType().getColumnSpan( factory );
|
||||
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 ) { // todo: should this instead check for exactly one row modified?
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
throw new StaleObjectStateException( lockable.getEntityName(), id );
|
||||
}
|
||||
|
||||
if ( lockable.isVersioned() ) {
|
||||
lockable.getVersionType().nullSafeSet( st, version, offset, session );
|
||||
}
|
||||
|
||||
int affected = st.executeUpdate();
|
||||
if ( affected < 0 ) { // todo: should this instead check for exactly one row modified?
|
||||
factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
|
||||
throw new StaleObjectStateException( lockable.getEntityName(), id );
|
||||
finally {
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
st.close();
|
||||
}
|
||||
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
JDBCException e = session.getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
catch ( SQLException e ) {
|
||||
throw session.getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
|
||||
sql
|
||||
);
|
||||
throw new PessimisticLockException("could not obtain pessimistic lock", e, object);
|
||||
}
|
||||
}
|
||||
catch (JDBCException e) {
|
||||
throw new PessimisticEntityLockException( object, "could not obtain pessimistic lock", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -45,9 +46,9 @@ import org.hibernate.sql.SimpleSelect;
|
|||
*
|
||||
* @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
|
||||
* @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
|
||||
* @since 3.2
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @since 3.2
|
||||
*/
|
||||
public class SelectLockingStrategy extends AbstractSelectLockingStrategy {
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect.lock;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
@ -44,13 +45,15 @@ import org.hibernate.sql.Update;
|
|||
* <p/>
|
||||
* This strategy is not valid for read style locks.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @since 3.2
|
||||
*/
|
||||
public class UpdateLockingStrategy implements LockingStrategy {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, UpdateLockingStrategy.class.getName());
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
UpdateLockingStrategy.class.getName()
|
||||
);
|
||||
|
||||
private final Lockable lockable;
|
||||
private final LockMode lockMode;
|
||||
|
@ -78,9 +81,7 @@ public class UpdateLockingStrategy implements LockingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LockingStrategy#lock
|
||||
*/
|
||||
@Override
|
||||
public void lock(
|
||||
Serializable id,
|
||||
Object version,
|
||||
|
|
|
@ -83,6 +83,9 @@ import org.hibernate.TransientObjectException;
|
|||
import org.hibernate.TypeMismatchException;
|
||||
import org.hibernate.UnresolvableObjectException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.lock.LockingStrategyException;
|
||||
import org.hibernate.dialect.lock.OptimisticEntityLockException;
|
||||
import org.hibernate.dialect.lock.PessimisticEntityLockException;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
|
||||
|
@ -1301,7 +1304,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( e instanceof org.hibernate.OptimisticLockException ) {
|
||||
else if ( e instanceof LockingStrategyException ) {
|
||||
PersistenceException converted = wrapLockException( e, lockOptions );
|
||||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
|
@ -1397,19 +1400,29 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
|
||||
public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
|
||||
PersistenceException pe;
|
||||
if ( e instanceof org.hibernate.OptimisticLockException ) {
|
||||
org.hibernate.OptimisticLockException ole = ( org.hibernate.OptimisticLockException ) e;
|
||||
pe = new OptimisticLockException( ole.getMessage(), ole, ole.getEntity() );
|
||||
final PersistenceException pe;
|
||||
if ( e instanceof OptimisticEntityLockException ) {
|
||||
final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
|
||||
pe = new OptimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
|
||||
}
|
||||
else if ( e instanceof org.hibernate.PessimisticLockException ) {
|
||||
org.hibernate.PessimisticLockException ple = ( org.hibernate.PessimisticLockException ) e;
|
||||
else if ( e instanceof PessimisticEntityLockException ) {
|
||||
PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
|
||||
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
|
||||
// assume lock timeout occurred if a timeout or NO WAIT was specified
|
||||
pe = new LockTimeoutException( ple.getMessage(), ple, ple.getEntity() );
|
||||
pe = new LockTimeoutException( lockException.getMessage(), lockException, lockException.getEntity() );
|
||||
}
|
||||
else {
|
||||
pe = new PessimisticLockException( ple.getMessage(), ple, ple.getEntity() );
|
||||
pe = new PessimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
|
||||
}
|
||||
}
|
||||
else if ( e instanceof org.hibernate.PessimisticLockException ) {
|
||||
org.hibernate.PessimisticLockException jdbcLockException = ( org.hibernate.PessimisticLockException ) e;
|
||||
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
|
||||
// assume lock timeout occurred if a timeout or NO WAIT was specified
|
||||
pe = new LockTimeoutException( jdbcLockException.getMessage(), jdbcLockException, null );
|
||||
}
|
||||
else {
|
||||
pe = new PessimisticLockException( jdbcLockException.getMessage(), jdbcLockException, null );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue