ozeigermann 2004/05/18 06:59:13
Modified: transaction/src/java/org/apache/commons/transaction/memory
TransactionalMapWrapper.java
Log:
- more transaction control
- refactored context to be a pure structure
Revision Changes Path
1.5 +122 -73
jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java
Index: TransactionalMapWrapper.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TransactionalMapWrapper.java 18 May 2004 07:40:29 -0000 1.4
+++ TransactionalMapWrapper.java 18 May 2004 13:59:13 -0000 1.5
@@ -31,6 +31,8 @@
import java.util.Map;
import java.util.Set;
+import javax.transaction.Status;
+
/**
* Wrapper that adds transactional control to all kinds of maps that implement the
[EMAIL PROTECTED] Map} interface.
* <br>
@@ -44,7 +46,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Oliver Zeigermann</a>
* @version $Revision$
*/
-public class TransactionalMapWrapper implements Map {
+public class TransactionalMapWrapper implements Map, Status {
protected Map wrapped;
@@ -54,6 +56,28 @@
this.wrapped = wrapped;
}
+ public synchronized boolean isReadOnly() {
+ TxContext txContext = getActiveTx();
+
+ if (txContext == null) {
+ throw new IllegalStateException(
+ "Active thread " + Thread.currentThread() + " not associated with a
transaction!");
+ }
+
+ return txContext.readOnly;
+ }
+
+ public synchronized boolean isTransactionMarkedForRollback() {
+ TxContext txContext = getActiveTx();
+
+ if (txContext == null) {
+ throw new IllegalStateException(
+ "Active thread " + Thread.currentThread() + " not associated with a
transaction!");
+ }
+
+ return txContext.rollbackOnly;
+ }
+
public synchronized void markTransactionForRollback() {
TxContext txContext = getActiveTx();
@@ -61,9 +85,9 @@
throw new IllegalStateException(
"Active thread " + Thread.currentThread() + " not associated with a
transaction!");
}
-
- txContext.setRollbackOnly(true);
-
+
+ txContext.rollbackOnly = true;
+
}
public synchronized TxContext suspendTransaction() {
@@ -74,7 +98,7 @@
"Active thread " + Thread.currentThread() + " not associated with a
transaction!");
}
- activeTx.set(null);
+ setActiveTx(null);
return txContext;
}
@@ -88,7 +112,16 @@
throw new IllegalStateException("No transaction to resume!");
}
- activeTx.set(suspendedTx);
+ setActiveTx(suspendedTx);
+ }
+
+ public synchronized int getTransactionState() {
+ TxContext txContext = getActiveTx();
+
+ if (txContext == null) {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+ return txContext.status;
}
public synchronized void startTransaction() {
@@ -96,7 +129,7 @@
throw new IllegalStateException(
"Active thread " + Thread.currentThread() + " already associated
with a transaction!");
}
- activeTx.set(new TxContext());
+ setActiveTx(new TxContext());
}
public synchronized void rollbackTransaction() {
@@ -108,7 +141,7 @@
}
// simply forget about tx
- activeTx.set(null);
+ setActiveTx(null);
}
public synchronized void commitTransaction() {
@@ -119,23 +152,26 @@
"Active thread " + Thread.currentThread() + " not associated with a
transaction!");
}
- if (txContext.isRollbackOnly()) {
- throw new IllegalStateException(
- "Active thread " + Thread.currentThread() + " is marked for
rollback!");
+ if (txContext.rollbackOnly) {
+ throw new IllegalStateException("Active thread " +
Thread.currentThread() + " is marked for rollback!");
}
- for (Iterator it = txContext.getChanges().entrySet().iterator();
it.hasNext();) {
+ if (txContext.cleared) {
+ wrapped.clear();
+ }
+
+ for (Iterator it = txContext.changes.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
wrapped.put(entry.getKey(), entry.getValue());
}
- for (Iterator it = txContext.getDeletes().iterator(); it.hasNext();) {
+ for (Iterator it = txContext.deletes.iterator(); it.hasNext();) {
Object key = it.next();
wrapped.remove(key);
}
// now forget about tx
- activeTx.set(null);
+ setActiveTx(null);
}
//
@@ -143,8 +179,15 @@
//
public synchronized void clear() {
- wrapped.clear();
- activeTx.set(null);
+ TxContext txContext = getActiveTx();
+ if (txContext == null) {
+ wrapped.clear();
+ } else {
+ txContext.readOnly = false;
+ txContext.cleared = true;
+ txContext.deletes.clear();
+ txContext.changes.clear();
+ }
}
public synchronized int size() {
@@ -152,8 +195,11 @@
TxContext txContext = getActiveTx();
if (txContext != null) {
- size += txContext.getChanges().size();
size -= txContext.deletes.size();
+ if (txContext.cleared) {
+ size = 0;
+ }
+ size += txContext.changes.size();
}
return size;
@@ -161,7 +207,7 @@
public synchronized boolean isEmpty() {
TxContext txContext = getActiveTx();
- if (txContext != null) {
+ if (txContext == null) {
return wrapped.isEmpty();
} else {
return (size() > 0);
@@ -174,7 +220,9 @@
if (txContext == null) {
return wrapped.containsKey(key);
} else {
- return (!txContext.getDeletes().contains(key) &&
txContext.getChanges().containsKey(key));
+ return (
+ (!txContext.cleared && wrapped.containsKey(key) &&
!txContext.deletes.contains(key))
+ || txContext.changes.containsKey(key));
}
}
@@ -213,16 +261,17 @@
wrapped.putAll(map);
} else {
try {
+ txContext.readOnly = false;
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
- txContext.getChanges().put(entry.getKey(), entry.getValue());
- txContext.getDeletes().remove(entry.getKey());
+ txContext.changes.put(entry.getKey(), entry.getValue());
+ txContext.deletes.remove(entry.getKey());
}
} catch (RuntimeException e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
} catch (Error e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
}
@@ -247,36 +296,40 @@
}
public synchronized Set keySet() {
- Set keySet = wrapped.keySet();
TxContext txContext = getActiveTx();
- if (txContext != null) {
- Set deleteSet = txContext.getDeletes();
- keySet.removeAll(deleteSet);
- Set changeSet = txContext.getChanges().keySet();
- keySet.addAll(changeSet);
+
+ if (txContext == null) {
+ return wrapped.keySet();
+ } else {
+ Set keySet = (txContext.cleared ? new HashSet() : wrapped.keySet());
+ keySet.removeAll(txContext.deletes);
+ keySet.addAll(txContext.changes.keySet());
+ return keySet;
}
- return keySet;
}
public synchronized Object get(Object key) {
TxContext txContext = getActiveTx();
if (txContext != null) {
- if (txContext.getDeletes().contains(key)) {
+ if (txContext.deletes.contains(key)) {
// reflects that entry has been deleted in this tx
return null;
}
- Object changed = txContext.getChanges().get(key);
+ Object changed = txContext.changes.get(key);
if (changed != null) {
// if object has been changed in this tx, get the local one
return changed;
}
}
- // as fall back return value from global cache (if present)
- return wrapped.get(key);
+ if (txContext == null || !txContext.cleared) {
+ // as fall back return value from global cache (if present)
+ return wrapped.get(key);
+ }
+ return null;
}
public synchronized Object remove(Object key) {
@@ -287,14 +340,16 @@
if (txContext == null) {
old = wrapped.remove(key);
} else {
+ old = get(key);
try {
- old = txContext.getChanges().remove(key);
- txContext.getDeletes().add(key);
+ txContext.readOnly = false;
+ txContext.changes.remove(key);
+ txContext.deletes.add(key);
} catch (RuntimeException e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
} catch (Error e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
}
}
@@ -311,13 +366,14 @@
wrapped.put(key, value);
} else {
try {
- txContext.getDeletes().remove(key);
- txContext.getChanges().put(key, value);
+ txContext.readOnly = false;
+ txContext.deletes.remove(key);
+ txContext.changes.put(key, value);
} catch (RuntimeException e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
} catch (Error e) {
- txContext.setRollbackOnly(true);
+ txContext.rollbackOnly = true;
throw e;
}
}
@@ -329,33 +385,8 @@
return (TxContext) activeTx.get();
}
- public static class TxContext {
- protected final Set deletes;
- protected final Map changes;
- protected boolean rollbackOnly;
-
- protected TxContext() {
- deletes = new HashSet();
- changes = new HashMap();
- rollbackOnly = false;
- }
-
- protected Map getChanges() {
- return changes;
- }
-
- protected Set getDeletes() {
- return deletes;
- }
-
- protected boolean isRollbackOnly() {
- return rollbackOnly;
- }
-
- protected void setRollbackOnly(boolean rollbackOnly) {
- this.rollbackOnly = rollbackOnly;
- }
-
+ protected void setActiveTx(TxContext txContext) {
+ activeTx.set(txContext);
}
// mostly copied from org.apache.commons.collections.map.AbstractHashedMap
@@ -402,6 +433,24 @@
public String toString() {
return new
StringBuffer().append(getKey()).append('=').append(getValue()).toString();
+ }
+ }
+
+ public static class TxContext {
+ protected final Set deletes;
+ protected final Map changes;
+ protected boolean rollbackOnly;
+ protected int status;
+ protected boolean cleared;
+ protected boolean readOnly;
+
+ protected TxContext() {
+ deletes = new HashSet();
+ changes = new HashMap();
+ rollbackOnly = false;
+ status = Status.STATUS_ACTIVE;
+ cleared = false;
+ readOnly = true;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]