Unit of Work(工作單元)是Axon架構中的一個重要概念,不過在大多數情況下,您不太可能直接與它互動。消息的處理被視為單個單元。Unit of Work(工作單元)的目的是協調在消息處理過程中執行的操作(指令或事件)。元件可以Unit of Work(工作單元)的每個階段上注冊執行的操作,比如onPrepareCommit或onCleanup。
你不太可能需要直接通路Unit of Work(工作單元)。它主要用于Axon提供的建構塊。如果你确實需要通路它,不管出于什麼原因,有一些方法可以獲得它。處理器Handler通過處理方法的參數接收Unit of Work(工作單元)。如果你開啟了注解驅動,那麼你可以向注解标注的方法中添加一個UnitOfWork類型的參數。在其他位置,您可以通過調用CurrentUnitOfWork.get()來檢索綁定到目前線程的工作單元。注意,如果沒有綁定到目前線程的工作單元,此方法将抛出異常。你可以使用CurrentUnitOfWork.isStarted()來檢查目前是否有可用的工作單元。
需要通路目前工作單元的一個原因是在消息處理過程中需要多次使用需要重用的資源,或者在工作單元完成時需要清理建立的資源。在這樣的情況下,unitOfWork.getOrComputeResource()和生命周期回調方法,如onRollback(),afterCommit()和onCleanup()允許您在此工作單元的處理過程中,聲明采取的行動。
Note:
注意,工作單元僅僅是更改的緩沖區,而不是事務的代替者。盡管所有的狀态更改都隻在送出工作單元時送出,但它的送出不是原子的。這意味着當一個送出失敗時,一些更改可能被持久化,而另一些則沒有。最佳實踐規定,指令不應該包含多個動作。如果你堅持這種做法,一個工作單元将會隻包含一個單獨的操作,使它可以安全地使用。如果你在工作機關有更多的動作,你可以考慮将一個Transaction(事務)附加到Unit of Work的送出中。使用unitofwork.oncommit(. .)來注冊在送出工作單元時需要采取的操作。
處理消息時,處理程式可能會抛出異常。預設情況下,未經檢查的異常将導緻UnitOfWork復原所有更改。是以,排程的副作用被取消了。
Axon提供了一些開箱即用的復原政策:
>RollbackConfigurationType.NEVER,工作的機關總是會送出
>RollbackConfigurationType.ANY_THROWABLE:将總是在異常發生時復原
>RollbackConfigurationType.UNCHECKED_EXCEPTIONS:将在Error或者運作時異常時復原
>RollbackConfigurationType.RUNTIME_EXCEPTION:僅僅在運作時異常時候復原(不包括Error)
當使用Axon元件處理消息時,将自動為您管理工作單元的生命周期。如果您選擇不使用這些元件,而是自己實作處理,您将需要以程式設計方式啟動和送出(或復原)一個工作單元。
在大多數情況下,DefaultUnitOfWork将為您提供所需的功能。它期望處理在一個線程内發生。在工作單元的上下文中執行任務,隻需要簡單地在建立的DefaultUnitOfWork上調用UnitOfWork.execute(Runnable)或UnitOfWork.executeWithResult。當任務完成時,工作單元将啟動并送出,或者在任務失敗時復原。如果需要更多的控制,您還可以選擇手動啟動、送出或復原工作單元。
典型用法如下:
UnitOfWork uow = DefaultUnitOfWork.startAndGet(message);
// then, either use the autocommit approach:
uow.executeWithResult(() -> ... logic here);
// or manually commit or rollback:
try {
// business logic comes here
uow.commit();
} catch (Exception e) {
uow.rollback(e);
// maybe rethrow...
}