Author: smarlow(a)redhat.com
Date: 2009-11-11 23:20:41 -0500 (Wed, 11 Nov 2009)
New Revision: 17962
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticForceIncrementLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticForceIncrementLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
Modified:
core/trunk/core/src/main/java/org/hibernate/LockMode.java
core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
Log:
HHH-4546 - add JPA 2.0 locking.
Modified: core/trunk/core/src/main/java/org/hibernate/LockMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/LockMode.java 2009-11-11 22:20:48 UTC (rev
17961)
+++ core/trunk/core/src/main/java/org/hibernate/LockMode.java 2009-11-12 04:20:41 UTC (rev
17962)
@@ -120,30 +120,30 @@
* Optimisticly assume that transaction will not experience contention for
* entities. The entity version will be verified near the transaction end.
*/
- public static final LockMode OPTIMISTIC = new LockMode(3,"OPTIMISTIC");
+ public static final LockMode OPTIMISTIC = new LockMode( 3, "OPTIMISTIC");
/**
* Optimisticly assume that transaction will not experience contention for entities.
* The entity version will be verified and incremented near the transaction end.
*/
- public static final LockMode OPTIMISTIC_FORCE_INCREMENT = new
LockMode(7,"OPTIMISTIC_FORCE_INCREMENT");
+ public static final LockMode OPTIMISTIC_FORCE_INCREMENT = new LockMode( 4,
"OPTIMISTIC_FORCE_INCREMENT");
/**
* Implemented as PESSIMISTIC_WRITE.
* TODO: introduce separate support for PESSIMISTIC_READ
*/
- public static final LockMode PESSIMISTIC_READ = new
LockMode(12,"PESSIMISTIC_READ");
+ public static final LockMode PESSIMISTIC_READ = new LockMode( 12,
"PESSIMISTIC_READ");
/**
* Transaction will obtain a database lock immediately.
* TODO: add PESSIMISTIC_WRITE_NOWAIT
*/
- public static final LockMode PESSIMISTIC_WRITE = new
LockMode(13,"PESSIMISTIC_WRITE");
+ public static final LockMode PESSIMISTIC_WRITE = new LockMode( 13,
"PESSIMISTIC_WRITE");
/**
* Transaction will immediately increment the entity version.
*/
- public static final LockMode PESSIMISTIC_FORCE_INCREMENT = new
LockMode(17,"PESSIMISTIC_FORCE_INCREMENT");
+ public static final LockMode PESSIMISTIC_FORCE_INCREMENT = new LockMode( 17,
"PESSIMISTIC_FORCE_INCREMENT");
/**
* end of javax.persistence.LockModeType modes
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -41,9 +41,7 @@
import org.hibernate.dialect.function.StandardJDBCEscapeFunction;
import org.hibernate.dialect.function.ConvertFunction;
import org.hibernate.dialect.function.ConditionalParenthesisFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.exception.CacheSQLStateConverter;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
@@ -564,7 +562,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// InterSystems Cache' does not current support "SELECT ... FOR UPDATE"
syntax...
// Set your transaction mode to READ_COMMITTED before using
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-11-11 22:20:48
UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-11-12 04:20:41
UTC (rev 17962)
@@ -48,8 +48,7 @@
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.exception.SQLExceptionConverter;
@@ -952,6 +951,21 @@
* @since 3.2
*/
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteSelectLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadSelectLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
return new SelectLockingStrategy( lockable, lockMode );
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -24,9 +24,7 @@
*/
package org.hibernate.dialect;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.LockMode;
@@ -104,7 +102,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -38,8 +38,7 @@
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.ViolatedConstraintNameExtracter;
@@ -292,7 +291,17 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// HSQLDB only supports READ_UNCOMMITTED transaction isolation
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
return new ReadUncommittedLockingStrategy( lockable, lockMode );
+
}
public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
@@ -300,12 +309,12 @@
super( lockable, lockMode );
}
- public void lock(Serializable id, Object version, Object object, SessionImplementor
session)
+ public void lock(Serializable id, Object version, Object object, int timeout,
SessionImplementor session)
throws StaleObjectStateException, JDBCException {
if ( getLockMode().greaterThan( LockMode.READ ) ) {
log.warn( "HSQLDB supports only READ_UNCOMMITTED isolation" );
}
- super.lock( id, version, object, session );
+ super.lock( id, version, object, timeout, session );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -31,9 +31,7 @@
import org.hibernate.persister.entity.Lockable;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.MckoiCaseFragment;
@@ -111,7 +109,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax...
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -24,9 +24,7 @@
*/
package org.hibernate.dialect;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.LockMode;
@@ -81,7 +79,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -27,9 +27,7 @@
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import java.sql.Types;
import org.hibernate.Hibernate;
@@ -336,7 +334,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax...
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -111,10 +111,15 @@
}
public String appendLockHint(LockMode mode, String tableName) {
- if ( mode.greaterThan( LockMode.READ ) ) {
- // does this need holdlock also? : return tableName + " with (updlock, rowlock,
holdlock)";
+ if ( ( mode == LockMode.UPGRADE ) ||
+ ( mode == LockMode.UPGRADE_NOWAIT ) ||
+ ( mode == LockMode.PESSIMISTIC_WRITE ) ||
+ ( mode == LockMode.WRITE ) ) {
return tableName + " with (updlock, rowlock)";
}
+ else if ( mode == LockMode.PESSIMISTIC_READ ) {
+ return tableName + " with (holdlock, rowlock)";
+ }
else {
return tableName;
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-11-11
22:20:48 UTC (rev 17961)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -32,9 +32,7 @@
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.*;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
@@ -217,7 +215,22 @@
public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
// TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax...
- if ( lockMode.greaterThan( LockMode.READ ) ) {
+ if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) {
+ return new PessimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_WRITE) {
+ return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.PESSIMISTIC_READ) {
+ return new PessimisticReadUpdateLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC) {
+ return new OptimisticLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) {
+ return new OptimisticForceIncrementLockingStrategy( lockable, lockMode);
+ }
+ else if ( lockMode.greaterThan( LockMode.READ ) ) {
return new UpdateLockingStrategy( lockable, lockMode );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java 2009-11-11
22:20:48 UTC (rev 17961)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -51,11 +51,12 @@
* @param id The id of the row to be locked
* @param version The current version (or null if not versioned)
* @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 optimisitic lock failure
* as part of acquiring the requested database lock.
* @throws JDBCException
*/
- public void lock(Serializable id, Object version, Object object, SessionImplementor
session)
+ public void lock(Serializable id, Object version, Object object, int timeout,
SessionImplementor session)
throws StaleObjectStateException, JDBCException;
}
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticForceIncrementLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticForceIncrementLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticForceIncrementLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,91 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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 java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.event.EventSource;
+import org.hibernate.action.EntityIncrementVersionProcess;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.persister.entity.Lockable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An optimistic locking strategy that forces an increment of the version (after
verifying that version hasn't changed).
+ * This takes place just prior to transaction commit.
+ * <p/>
+ * This strategy is valid for LockMode.OPTIMISTIC_FORCE_INCREMENT
+ *
+ * @since 3.5
+ *
+ * @author Scott Marlow
+ */
+public class OptimisticForceIncrementLockingStrategy implements LockingStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
OptimisticForceIncrementLockingStrategy.class );
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+ /**
+ * Construct locking strategy.
+ *
+ * @param lockable The metadata for the entity to be locked.
+ * @param lockMode Indictates the type of lock to be acquired.
+ */
+ public OptimisticForceIncrementLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ if ( lockMode.lessThan( LockMode.OPTIMISTIC_FORCE_INCREMENT ) ) {
+ throw new HibernateException( "[" + lockMode + "] not valid for ["
+ lockable.getEntityName() + "]" );
+ }
+ }
+
+ /**
+ * @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( "[" + lockMode + "] not supported for
non-versioned entities [" + lockable.getEntityName() + "]" );
+ }
+ EntityEntry entry = session.getPersistenceContext().getEntry(object);
+ EntityIncrementVersionProcess incrementVersion = new
EntityIncrementVersionProcess(object, entry);
+ EventSource source = (EventSource)session;
+ // Register the EntityIncrementVersionProcess action to run just prior to transaction
commit.
+ source.getActionQueue().registerProcess(incrementVersion);
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/OptimisticLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,88 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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 java.io.Serializable;
+
+import org.hibernate.*;
+import org.hibernate.event.EventSource;
+import org.hibernate.action.EntityVerifyVersionProcess;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.persister.entity.Lockable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An optimistic locking strategy that verifies that the version hasn't changed
(prior to transaction commit).
+ * <p/>
+ * This strategy is valid for LockMode.OPTIMISTIC
+ *
+ * @since 3.5
+ *
+ * @author Scott Marlow
+ */
+public class OptimisticLockingStrategy implements LockingStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
OptimisticLockingStrategy.class );
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+
+ /**
+ * Construct locking strategy.
+ *
+ * @param lockable The metadata for the entity to be locked.
+ * @param lockMode Indictates the type of lock to be acquired.
+ */
+ public OptimisticLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ if ( lockMode.lessThan( LockMode.OPTIMISTIC ) ) {
+ throw new HibernateException( "[" + lockMode + "] not valid for ["
+ lockable.getEntityName() + "]" );
+ }
+ }
+
+ /**
+ * @see org.hibernate.dialect.lock.LockingStrategy#lock
+ */
+ public void lock(
+ Serializable id,
+ Object version,
+ Object object,
+ int timeout, SessionImplementor session) throws StaleObjectStateException,
JDBCException {
+ if ( !lockable.isVersioned() ) {
+ throw new OptimisticLockException( "[" + lockMode + "] not supported
for non-versioned entities [" + lockable.getEntityName() + "]" );
+ }
+ EntityEntry entry = session.getPersistenceContext().getEntry(object);
+ EventSource source = (EventSource)session;
+ EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(object,
entry);
+ // Register the EntityVerifyVersionProcess action to run just prior to transaction
commit.
+ source.getActionQueue().registerProcess(verifyVersion);
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticForceIncrementLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticForceIncrementLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticForceIncrementLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,93 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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 java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.persister.entity.EntityPersister;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A pessimistic locking strategy that increments the version immediately (obtaining an
exclusive write lock).
+ * <p/>
+ * This strategy is valid for LockMode.PESSIMISTIC_FORCE_INCREMENT
+ *
+ * @since 3.5
+ *
+ * @author Scott Marlow
+ */
+public class PessimisticForceIncrementLockingStrategy implements LockingStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
PessimisticForceIncrementLockingStrategy.class );
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+
+ /**
+ * Construct locking strategy.
+ *
+ * @param lockable The metadata for the entity to be locked.
+ * @param lockMode Indictates the type of lock to be acquired.
+ */
+ public PessimisticForceIncrementLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ // ForceIncrement can be used for PESSIMISTIC_READ, PESSIMISTIC_WRITE or
PESSIMISTIC_FORCE_INCREMENT
+ if ( lockMode.lessThan( LockMode.PESSIMISTIC_READ ) ) {
+ throw new HibernateException( "[" + lockMode + "] not valid for ["
+ lockable.getEntityName() + "]" );
+ }
+ }
+
+ /**
+ * @see org.hibernate.dialect.lock.LockingStrategy#lock
+ */
+ public void lock(
+ Serializable id,
+ Object version,
+ Object object,
+ int timeout,
+ SessionImplementor session) throws StaleObjectStateException, JDBCException {
+ if ( !lockable.isVersioned() ) {
+ throw new HibernateException( "[" + lockMode + "] not supported for
non-versioned entities [" + lockable.getEntityName() + "]" );
+ }
+ EntityEntry entry = session.getPersistenceContext().getEntry(object);
+ final EntityPersister persister = entry.getPersister();
+ Object nextVersion = persister.forceVersionIncrement(
+ entry.getId(), entry.getVersion(), session
+ );
+ entry.forceLocked( object, nextVersion );
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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.persister.entity.Lockable;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * A pessimistic locking strategy where the locks are obtained through select
statements.
+ * <p/>
+ * For non-read locks, this is achieved through the Dialect's specific
+ * SELECT ... FOR UPDATE syntax.
+ *
+ * This strategy is valid for LockMode.PESSIMISTIC_READ
+ *
+ * This class is a clone of SelectLockingStrategy.
+ *
+ * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
+ * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
+ * @since 3.5
+ *
+ * @author Steve Ebersole
+ * @author Scott Marlow
+ */
+public class PessimisticReadSelectLockingStrategy implements LockingStrategy {
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+ private final String sql;
+
+ /**
+ * Construct a locking strategy based on SQL SELECT statements.
+ *
+ * @param lockable The metadata for the entity to be locked.
+ * @param lockMode Indictates the type of lock to be acquired.
+ */
+ public PessimisticReadSelectLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ this.sql = generateLockString();
+ }
+
+ /**
+ * @see org.hibernate.dialect.lock.LockingStrategy#lock
+ */
+ public void lock(
+ Serializable id,
+ Object version,
+ Object object,
+ int timeout, 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
+ );
+ }
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+
+ 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();
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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 java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.sql.Update;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A pessimistic locking strategy where the locks are obtained through update
statements.
+ * <p/>
+ * This strategy is valid for LockMode.PESSIMISTIC_READ
+ *
+ * This class is a clone of UpdateLockingStrategy.
+ *
+ * @since 3.5
+ *
+ * @author Steve Ebersole
+ * @author Scott Marlow
+ */
+public class PessimisticReadUpdateLockingStrategy implements LockingStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
PessimisticReadUpdateLockingStrategy.class );
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+ private final String 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 PessimisticReadUpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ if ( lockMode.lessThan( LockMode.PESSIMISTIC_READ ) ) {
+ 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();
+ }
+ }
+
+ /**
+ * @see org.hibernate.dialect.lock.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() + "]" );
+ }
+ 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 ) { // todo: should this instead check for exactly one row
modified?
+ 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
+ );
+ }
+ }
+
+ protected String generateLockString() {
+ SessionFactoryImplementor factory = lockable.getFactory();
+ Update update = new Update( factory.getDialect() );
+ update.setTableName( lockable.getRootTableName() );
+ update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() );
+ update.setVersionColumnName( lockable.getVersionColumnName() );
+ update.addColumn( lockable.getVersionColumnName() );
+ if ( factory.getSettings().isCommentsEnabled() ) {
+ update.setComment( lockMode + " lock " + lockable.getEntityName() );
+ }
+ return update.toStatementString();
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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.persister.entity.Lockable;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * A pessimistic locking strategy where the locks are obtained through select
statements.
+ * <p/>
+ * For non-read locks, this is achieved through the Dialect's specific
+ * SELECT ... FOR UPDATE syntax.
+ *
+ * This strategy is valid for LockMode.PESSIMISTIC_WRITE
+ *
+ * This class is a clone of SelectLockingStrategy.
+ *
+ * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
+ * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
+ * @since 3.5
+ *
+ * @author Steve Ebersole
+ * @author Scott Marlow
+ */
+public class PessimisticWriteSelectLockingStrategy implements LockingStrategy {
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+ private final String sql;
+
+ /**
+ * Construct a locking strategy based on SQL SELECT statements.
+ *
+ * @param lockable The metadata for the entity to be locked.
+ * @param lockMode Indictates the type of lock to be acquired.
+ */
+ public PessimisticWriteSelectLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ this.sql = generateLockString();
+ }
+
+ /**
+ * @see LockingStrategy#lock
+ */
+ public void lock(
+ Serializable id,
+ Object version,
+ Object object,
+ int timeout, 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
+ );
+ }
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+
+ 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();
+ }
+}
\ No newline at end of file
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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 java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.sql.Update;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A pessimistic locking strategy where the locks are obtained through update
statements.
+ * <p/>
+ * This strategy is valid for LockMode.PESSIMISTIC_WRITE
+ *
+ * This class is a clone of UpdateLockingStrategy.
+ *
+ * @since 3.5
+ *
+ * @author Steve Ebersole
+ * @author Scott Marlow
+ */
+public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
PessimisticWriteUpdateLockingStrategy.class );
+
+ private final Lockable lockable;
+ private final LockMode lockMode;
+ private final String 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 PessimisticWriteUpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
+ this.lockable = lockable;
+ this.lockMode = lockMode;
+ if ( lockMode.lessThan( LockMode.PESSIMISTIC_READ ) ) {
+ 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();
+ }
+ }
+
+ /**
+ * @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() + "]" );
+ }
+ 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 ) { // todo: should this instead check for exactly one row
modified?
+ 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
+ );
+ }
+ }
+
+ protected String generateLockString() {
+ SessionFactoryImplementor factory = lockable.getFactory();
+ Update update = new Update( factory.getDialect() );
+ update.setTableName( lockable.getRootTableName() );
+ update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() );
+ update.setVersionColumnName( lockable.getVersionColumnName() );
+ update.addColumn( lockable.getVersionColumnName() );
+ if ( factory.getSettings().isCommentsEnabled() ) {
+ update.setComment( lockMode + " lock " + lockable.getEntityName() );
+ }
+ return update.toStatementString();
+ }
+
+ protected LockMode getLockMode() {
+ return lockMode;
+ }
+}
\ No newline at end of file
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java 2009-11-11
22:20:48 UTC (rev 17961)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -76,6 +76,7 @@
Serializable id,
Object version,
Object object,
+ int timeout,
SessionImplementor session) throws StaleObjectStateException, JDBCException {
SessionFactoryImplementor factory = session.getFactory();
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java 2009-11-11
22:20:48 UTC (rev 17961)
+++
core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -83,9 +83,10 @@
* @see LockingStrategy#lock
*/
public void lock(
- Serializable id,
+ 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() + "]" );
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java 2009-11-11
22:20:48 UTC (rev 17961)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -100,27 +100,13 @@
}
try {
- if ( persister.isVersioned() && (requestedLockMode == LockMode.FORCE ||
requestedLockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) ) {
+ if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) {
// todo : should we check the current isolation mode explicitly?
Object nextVersion = persister.forceVersionIncrement(
entry.getId(), entry.getVersion(), source
);
entry.forceLocked( object, nextVersion );
}
- else if ( requestedLockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) {
- if(!persister.isVersioned()) {
- throw new OptimisticLockException("force: Version column is not mapped for
" + entry.getPersister().getEntityName(), object);
- }
- EntityIncrementVersionProcess incrementVersion = new
EntityIncrementVersionProcess(object, entry);
- source.getActionQueue().registerProcess(incrementVersion);
- }
- else if ( requestedLockMode == LockMode.OPTIMISTIC ) {
- if(!persister.isVersioned()) {
- throw new OptimisticLockException("Version column is not mapped for " +
entry.getPersister().getEntityName(), object);
- }
- EntityVerifyVersionProcess verifyVersion = new EntityVerifyVersionProcess(object,
entry);
- source.getActionQueue().registerProcess(verifyVersion);
- }
else {
persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source
);
}
Modified:
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2009-11-11
22:20:48 UTC (rev 17961)
+++
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2009-11-12
04:20:41 UTC (rev 17962)
@@ -1412,7 +1412,7 @@
Object object,
LockMode lockMode,
SessionImplementor session) throws HibernateException {
- getLocker( lockMode ).lock( id, version, object, session );
+ getLocker( lockMode ).lock( id, version, object, -1, session );
}
public String getRootTableName() {