An implementation of basic
Transaction
semantics designed to work in concert withBasicChannelSemantics
to simplify creation of robustChannel
implementations. This class ensures that each transaction implementation method is called only while the transaction is in the correct state for that method, and only by the thread that created the transaction. Nested calls tobegin()
andclose()
are supported as long as they are balanced.Subclasses need only implement
doPut
,doTake
,doCommit
, anddoRollback
, and the developer can rest assured that those methods are called only after transaction state preconditions have been properly met.doBegin
anddoClose
may also be implemented if there is work to be done at those points.All InterruptedException exceptions thrown from the implementations of the
doXXX
methods are automatically wrapped to become ChannelExceptions, but only after restoring the interrupted status of the thread so that any subsequent blocking method calls will themselves throw InterruptedException rather than blocking. The exception to this rule isdoTake
, which simply returns null instead of wrapping and propagating the InterruptedException, though it still first restores the interrupted status of the thread.
BasicTransactionSemantics實現了Transaction的基本語法,與BasicChannelSemantics一起工作,來使得建立健壯的Channel實現更加簡單。這個類確保了一個事務中的操作(如take(),put())只有在當前的事務處於對應的狀態時才被呼叫,並且只有建立了當前的事務的執行緒才能呼叫這些事務中的操作。對begin()和close()的巢狀呼叫是支援的,只要對它們的呼叫保持平衡(這句不怎麼明白,對同一個transaction物件巢狀呼叫這兩個方法明顯不行,應該是不同的transaction物件的close和begin方法可以巢狀)。
它的子類可以只實現doPut, doTake, doCommit和doCommit、doRollback方法,而不必再設法確保這些方法只有在正確的事務狀態下才被呼叫。當doBegin和doClose也有特殊的操作時,也可以實現這兩個方法。
在doXXX方法中丟擲的InterruptedException都被包裝進ChannelException中,但這是在恢復了當前執行緒的interrupted狀態之後,這樣接下的blocking method call就會丟擲InterruptedException,而不是進入阻塞狀態。這個規則的的例外是doTake,當只是返回null,而不是包裝、傳播InterruptedException,但是doTake仍然先恢復了執行緒的interrupted狀態。
BasicTransactionSemantics實現了跟事務範圍內各個操作有關方法。
Method Summary void
begin()
Starts a transaction boundary for the current channel operation.void
close()
Ends a transaction boundary for the current channel operation.void
commit()
Indicates that the transaction can be successfully committed.protected void
doBegin()
protected void
doClose()
protected abstract void
doCommit()
protected abstract void
doPut(Event event)
protected abstract void
doRollback()
protected abstract Event
doTake()
protected BasicTransactionSemantics.State
getState()
protected void
put(Event event)
The method to whichBasicChannelSemantics
delegates calls toput
.void
rollback()
Indicates that the transaction can must be aborted.protected Event
take()
The method to whichBasicChannelSemantics
delegates calls totake
.String
toString()
其中put take begin close commit rollback 的結構都很相似。主要結構都是確保這些操作時Transaction在正確的對應狀態,然後呼叫doXXX方法。如果當前的執行緒不擁有當前的事務或者事務的狀態不對,就丟擲異常。如果doXXX方法丟擲InterruptedException就通過Thread.currentThread.interrupt()方法恢復當前執行緒的interrupted狀態,然後將捕獲的InterruptedException包裝成一個ChannelException,丟擲。
@Override public void rollback() { Preconditions.checkState(Thread.currentThread().getId() == initialThreadId, "rollback() called from different thread than getTransaction()!"); Preconditions.checkState(state.equals(State.OPEN), "rollback() called when transaction is %s!", state); state = State.COMPLETED; try { doRollback(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new ChannelException(e.toString(), e); } }
可見BasicTransactionSemantic類確保了事務中各個操作的執行順序。並且對執行各個操作中可能丟擲的InterruptedException進行了一次封裝。它的各個子類只需要實現具體的操作。
以BasicChannelSemantic類的程式碼可以看出,它對Channel介面定義的put(event)和take()的實現是把這兩個方法代理給了自己執行緒中的BasicTransactionSemantic的put和get方法。而BasicTransactionSemantic中這兩個方法
protected Event take() { Preconditions.checkState(Thread.currentThread().getId() == initialThreadId, "take() called from different thread than getTransaction()!"); Preconditions.checkState(state.equals(State.OPEN), "take() called when transaction is %s!", state); try { return doTake(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; } }
是交給了子類要實現的doTake和doPut方法。因此一個Channel的具體實現,其訊息的處理邏輯是由自己的getTransaction()方法返回的Trasaction物件來實現的。正如MemoryChannel的內部類MemoryTransaction所做的一樣。