Re: Transactional Queue
Jean Morissette <[email protected]> Sun, 05 Dec 2004 01:38:03 -0500
| Newsgroups | gmane.comp.java.seda.user |
|---|---|
| Message-ID | <[email protected]> |
Quartz wrote:
>>So, the user would just need to call 1 time commit() or, if an exception
>>occur, 1 time abort(). But, who should create the Transaction object?
>
>
> I haven't used that yet. First guess, just pass the first key to an overloaded enqueue_prepare.
> If key is known by the sink, it just appends to whetever was prepared.
> Object key = queue1.enqueue_prepare(x); //or pass null key, but poor api.
> queue2.enqueue_prepare(key, x);
> queue3.enqueue_prepare(key, x);
>
> And if you really want a txn object with .abort(), just give the key (txn) class the power to
> remove itself from its hosting weakhashmap of key-to-prepares. So, for txm object, it sure comes
> from the sink upon request (explicit, or collateral of first prepare).
>
So, the solution could be to create a TransactionIF:
public interface TransactionIF {
void commit();
void abort();
/**
* Combine the given transaction to the current one. So, committing
* the current transaction would also commit the given one, but
* the not the inverse.
* It's provided mainly for internal purpose.
*/
void join(TransactionIF txn);
}
And modify SinkIF to remove enqueue_commit and enqueue_abort:
public interface SinkIF {
...
/** Start a new transaction. */
TransactionIF enqueue_prepare(QueueElement x);
/** Continue a transaction */
void enqueue_prepare(QueueElement x, TransactionIF txn);
}
And finally, an example of a SinkIF implementation:
class MyQueue implements QueueIF {
...
public TransactionIF enqueue_prepare(QueueElementIF[] x) {
// reserve space
TxnImpl newTxn = new TxnImpl();
txnMap.put(newTxn, x);
return newTxn;
}
public void enqueue_prepare(QueueElementIF[] x, TransactionIF txn) {
// reserve space
TxnImpl newTxn = new TxnImpl();
txnMap.put(newTxn, x);
txn.join(newTxn); // we combine the two transactions
}
// inner class
class TxnImpl implements TransactionIF {
TransactionIF joinedTxn;
public void commit() {
MyQueue.this.do_commit(this);
joinedTxn.commit();
}
public void abort() {
MyQueue.this.do_abort(this);
joinedTxn.abort();
}
// Link the given transaction
public void join(TransactionIF txn) {
if (joinedTxn == null)
joinedTxn = txn;
else
joinedTxn.join(txn);
}
// Protect "dangling prepares"
protected void finalize() throws Throwable {
abort();
}
}
}
Do do like what you see? Me, I like it :-)
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/