You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2007/08/10 18:27:23 UTC
svn commit: r564653 - in /lenya/trunk/src:
java/org/apache/lenya/cms/repository/ java/org/apache/lenya/transaction/
modules-core/usecase/java/src/org/apache/lenya/cms/usecase/
Author: andreas
Date: Fri Aug 10 09:27:21 2007
New Revision: 564653
URL: http://svn.apache.org/viewvc?view=rev&rev=564653
Log:
Introduced global transaction lock
Added:
lenya/trunk/src/java/org/apache/lenya/transaction/TransactionLock.java
Modified:
lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java
lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java
lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java
Modified: lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java?view=diff&rev=564653&r1=564652&r2=564653
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/repository/SessionImpl.java Fri Aug 10 09:27:21 2007
@@ -54,7 +54,8 @@
/**
* Ctor.
* @param identity The identity.
- * @param modifiable Determins if the repository items in this session can be modified.
+ * @param modifiable Determins if the repository items in this session can
+ * be modified.
* @param manager The service manager.
* @param logger The logger.
*/
@@ -67,13 +68,13 @@
this.identityMap = new IdentityMapImpl(logger);
this.identity = identity;
-
+
ObservationRegistry registry = null;
UUIDGenerator generator = null;
try {
registry = (ObservationRegistry) this.manager.lookup(ObservationRegistry.ROLE);
addListener(registry);
-
+
generator = (UUIDGenerator) this.manager.lookup(UUIDGenerator.ROLE);
this.id = generator.nextUUID();
} catch (Exception e) {
@@ -86,7 +87,7 @@
this.manager.release(generator);
}
}
-
+
if (modifiable) {
this.unitOfWork = new UnitOfWorkImpl(this.identityMap, this.identity, getLogger());
}
@@ -109,6 +110,8 @@
return this.unitOfWork;
}
+ private boolean committed = false;
+
/**
* Commits the transaction.
* @throws RepositoryException if an error occurs.
@@ -126,6 +129,8 @@
throw new RepositoryException(e);
}
+ this.committed = true;
+
for (Iterator i = this.events.iterator(); i.hasNext();) {
RepositoryEvent event = (RepositoryEvent) i.next();
for (Iterator l = this.listeners.iterator(); l.hasNext();) {
@@ -148,7 +153,7 @@
}
this.events.clear();
}
-
+
protected SharedItemStore getSharedItemStore() {
if (this.sharedItemStore == null) {
try {
@@ -166,11 +171,10 @@
*/
public RepositoryItem getRepositoryItem(RepositoryItemFactory factory, String key)
throws RepositoryException {
-
+
if (!isModifiable() && factory.isSharable()) {
return getSharedItemStore().getRepositoryItem(factory, key);
- }
- else {
+ } else {
RepositoryItemFactoryWrapper wrapper = new RepositoryItemFactoryWrapper(factory, this);
return (RepositoryItem) getIdentityMap().get(wrapper, key);
}
@@ -224,10 +228,15 @@
private List events = new ArrayList();
private IdentityMap identityMap;
- public void enqueueEvent(RepositoryEvent event) {
+ public synchronized void enqueueEvent(RepositoryEvent event) {
if (!isModifiable()) {
throw new RuntimeException("Can't enqueue event in unmodifiable session!");
}
+ if (committed) {
+ throw new RuntimeException(
+ "No events can be queued after the session has been committed. Event: ["
+ + event.getDescriptor() + "]");
+ }
Assert.isTrue("event belongs to session", event.getSession() == this);
this.events.add(event);
}
@@ -239,7 +248,7 @@
public boolean isModifiable() {
return this.unitOfWork != null;
}
-
+
private String id;
public String getId() {
Added: lenya/trunk/src/java/org/apache/lenya/transaction/TransactionLock.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/transaction/TransactionLock.java?view=auto&rev=564653
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/transaction/TransactionLock.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/transaction/TransactionLock.java Fri Aug 10 09:27:21 2007
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.transaction;
+
+/**
+ * Global transaction lock.
+ */
+public class TransactionLock {
+
+ public static final Object LOCK = TransactionLock.class;
+
+}
Modified: lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java?view=diff&rev=564653&r1=564652&r2=564653
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/transaction/UnitOfWorkImpl.java Fri Aug 10 09:27:21 2007
@@ -88,8 +88,6 @@
this.removedObjects.add(object);
}
- private static Object classLock = UnitOfWorkImpl.class;
-
/**
* Commit the transaction. We lock this method for the whole class to avoid
* synchronization problems.
@@ -100,7 +98,7 @@
getLogger().debug("UnitOfWorkImpl::commit() called");
}
- synchronized (classLock) {
+ synchronized (TransactionLock.LOCK) {
Set lockedObjects = this.locks.keySet();
@@ -186,7 +184,7 @@
if (getLogger().isDebugEnabled()) {
getLogger().debug("UnitOfWorkImpl::rollback() called");
}
- synchronized (classLock) {
+ synchronized (TransactionLock.LOCK) {
if (getIdentityMap() != null) {
Object[] objects = getIdentityMap().getObjects();
for (int i = 0; i < objects.length; i++) {
Modified: lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java?view=diff&rev=564653&r1=564652&r2=564653
==============================================================================
--- lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java (original)
+++ lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/usecase/AbstractUsecase.java Fri Aug 10 09:27:21 2007
@@ -47,6 +47,7 @@
import org.apache.lenya.cms.repository.Session;
import org.apache.lenya.transaction.ConcurrentModificationException;
import org.apache.lenya.transaction.LockException;
+import org.apache.lenya.transaction.TransactionLock;
/**
* Abstract usecase implementation.
@@ -305,8 +306,8 @@
getSession().rollback();
}
} catch (ConcurrentModificationException e) {
- getLogger().error(
- "Could not commit usecase [" + getName() + "]: " + e.getMessage());
+ getLogger()
+ .error("Could not commit usecase [" + getName() + "]: " + e.getMessage());
addErrorMessage(e.getMessage());
} catch (Exception e1) {
getLogger().error("Could not commit/rollback usecase [" + getName() + "]: ", e1);
@@ -729,6 +730,10 @@
}
/**
+ * <p>
+ * This method is locked via the class lock to avoid inter-usecase
+ * synchronization issues.
+ * </p>
* @see org.apache.lenya.cms.usecase.Usecase#lockInvolvedObjects()
*/
public final void lockInvolvedObjects() throws UsecaseException {
@@ -738,7 +743,9 @@
} catch (RepositoryException e) {
throw new UsecaseException(e);
}
- lockInvolvedObjects(getNodesToLock());
+ synchronized (TransactionLock.LOCK) {
+ lockInvolvedObjects(getNodesToLock());
+ }
}
protected void startTransaction() throws RepositoryException {
@@ -748,11 +755,13 @@
}
/**
+ * <p>
* Lock the objects, for example when you need to change them (for example,
* delete). If you know when entering the usecase what these objects are,
* you do not need to call this, the framework will take of it if you
* implement getObjectsToLock(). If you do not know in advance what the
* objects are, you can call this method explicitly when appropriate.
+ * </p>
*
* @param objects the transactionable objects to lock
* @throws UsecaseException if an error occurs.
@@ -760,18 +769,9 @@
* @see #getNodesToLock()
*/
public final void lockInvolvedObjects(Node[] objects) throws UsecaseException {
-
- if (getLogger().isDebugEnabled())
- getLogger().debug(
- "AbstractUsecase::lockInvolvedObjects() called, are there objects to lock ? "
- + (objects != null));
-
try {
for (int i = 0; i < objects.length; i++) {
if (!objects[i].isLocked()) {
- if (getLogger().isDebugEnabled())
- getLogger().debug(
- "AbstractUsecase::lockInvolvedObjects() locking " + objects[i]);
objects[i].lock();
}
if (!isOptimistic() && !objects[i].isCheckedOutBySession()) {
@@ -788,11 +788,11 @@
for (int i = 0; i < objects.length; i++) {
if (objects[i].isCheckedOut() && !objects[i].isCheckedOutBySession()) {
- if (getLogger().isDebugEnabled())
+ if (getLogger().isDebugEnabled()) {
getLogger().debug(
"AbstractUsecase::lockInvolvedObjects() can not execute, object ["
+ objects[i] + "] is already checked out");
-
+ }
canExecute = false;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org