public class MemoryChannel extends BasicChannelSemantics public abstract class BasicChannelSemantics extends AbstractChannel public abstract class AbstractChannel implements Channel, LifecycleAware, Configurable
AbstractChannel只在實現了LifecycleAware,NamedComponent和Configurable中的一些介面,除了對部分方法進行了同步,沒什麼特殊。
BasicChannelSemantics是實現事務機制的關鍵之一
* <p>
* An implementation of basic {@link Channel} semantics, including the
* implied thread-local semantics of the {@link Transaction} class,
* which is required to extend {@link BasicTransactionSemantics}.
* </p>
*/
BasicChannelSemantics實現了基礎的Channel語法,包括了Transaction的thread-local語法。
首先BasicChannelSemantics類持有一個ThreadLocal物件,它維護了一個BasicTransactionSemantics物件。BasicTransationSementics是一個abstract class,提供了Transaction介面的基礎實現。
這些每個執行緒都包括了一個唯一的Transaction物件,保證了事務的隔離性。
private ThreadLocal<BasicTransactionSemantics> currentTransaction = new ThreadLocal<BasicTransactionSemantics>();
線上程中獲取當前執行緒中的事務通過getTransaction方法,它會呼叫BasicChannelSemantics中定義的的抽象方法createTransaction()來獲取BasicTransactionSemantics的例項。
/** * <p> * Initializes the channel if it is not already, then checks to see * if there is an open transaction for this thread, creating a new * one via <code>createTransaction</code> if not. * @return the current <code>Transaction</code> object for the * calling thread * </p> */ @Override public Transaction getTransaction() { if (!initialized) { synchronized (this) { if (!initialized) { initialize(); initialized = true; } } } BasicTransactionSemantics transaction = currentTransaction.get(); if (transaction == null || transaction.getState().equals( BasicTransactionSemantics.State.CLOSED)) { transaction = createTransaction(); currentTransaction.set(transaction); } return transaction; }
首先,Channel使用了延遲初始化的機制。只有在Channel第一次被呼叫getTransaction()時,它的initialize()方法才被呼叫。
當currentTransaction中並不包含一個BasicTransactionSemantics物件的時候,或者當前的transaction物件已經處理CLOSED狀態的時候,它就呼叫createTransaction方法來獲取一個Transaction,並設定給thread-local的currentTransaction。
至此,Transaction的thread-local機制已實現。
那麼Channel是如何利用thread-local的Transaction物件來實現訊息存取的事務呢?它只是確保事務已開啟,然後將訊息的存取功能代理給本執行緒的transaction物件。
@Override public void put(Event event) throws ChannelException { BasicTransactionSemantics transaction = currentTransaction.get(); Preconditions.checkState(transaction != null, "No transaction exists for this thread"); transaction.put(event); }
@Override
public Event take() throws ChannelException {
BasicTransactionSemantics transaction = currentTransaction.get();
Preconditions.checkState(transaction != null,
"No transaction exists for this thread");
return transaction.take();
}