Class NotificationOutboxBase
- All Implemented Interfaces:
OutboxView
通知遞送 Outbox 列的欄位基類(每收件人 × 每通道一列)
是 transactional outbox 與遞送稽核的載體:NotificationService
渲染後寫入 PENDING 列,fast-path 與輪詢器經 NotificationOutboxDispatcher 遞送並更新狀態。
本列即遞送稽核(狀態、嘗試次數、最後錯誤、時間)。
依 ADR-017:框架 jar
不擁有 @Entity——本類為 @MappedSuperclass(欄位 + 狀態機邏輯),具體 @Entity(表名、唯一
約束、租戶性)由應用宣告。租戶欄位不在此(決策二):tenant 專案的應用 entity 以 @TenantId
宣告——請求緒寫入時 Hibernate 自動注入當前租戶、去重查詢自動限縮該租戶;排程/輪詢緒(root)不受
filter、天然跨租戶撈取(決策三的推導)。ownership 專案無租戶欄位。跨 async 邊界重建租戶 context
時,dispatcher 以 TenantAware 探詢本列租戶(見 NotificationOutboxDispatcher)。
dedupeKey 在租戶內唯一(冪等去重):同鍵不重複建列,避免同一業務事件重送。呼叫端未提供去重鍵時,
該列取得每列自成一鍵的唯一值(=不參與去重),而非 null——見 dedupeKey 欄位說明與 ADR-017 決策五。
- Since:
- 4.0.0
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription取得 EMAIL CC 位址;非 EMAIL 或舊資料列回空清單。protected void讓直接建立的待送列沿用 auditing 所寫入的建立時間,避免nextAttemptAt=null導致輪詢器永遠撈不到。Entity callback 於 entity listener 之後執行,因此可安全使用createdDate;若應用未啟用 Spring Data JPA auditing,則明確失敗而非靜默漏送。void標記遞送成功(終態)。voidmarkSuppressed(String error) 標記因政策被抑制(終態,不重試)。用於確定性封鎖,如郵件防火牆全擋——重試無益, 故不增attempts、不排重試,直接轉SUPPRESSED(與DEAD重試耗盡區分)。voidrecordFailure(String error, Instant nextAttemptTime) 記錄一次遞送失敗;依是否逾重試上限轉FAILED(排定重試)或DEAD(放棄)void重排此列供重送(人工補救入口):把終態 /SENT/FAILED列重置為PENDING並排定即刻遞送 ——status=PENDING、attempts=0、nextAttemptAt=now、清除lastError與sentAt;voidsetCcRecipientAddresses(List<String> addresses) 設定 EMAIL CC 位址並序列化保存。Methods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface OutboxView
getAttempts, getBody, getChannel, getCreatedDate, getDedupeKey, getDeepLink, getDeliveryExpiresAt, getId, getLastError, getLastModifiedDate, getMaxAttempts, getNextAttemptAt, getRecipientAddress, getRecipientUserId, getSentAt, getStatus, getSubject, getType
-
Field Details
-
MAX_ERROR_LENGTH
public static final int MAX_ERROR_LENGTH最後錯誤訊息保留的最大長度(超出截斷)- See Also:
-
-
Constructor Details
-
NotificationOutboxBase
public NotificationOutboxBase()
-
-
Method Details
-
getCcRecipientAddresses
取得 EMAIL CC 位址;非 EMAIL 或舊資料列回空清單。- Specified by:
getCcRecipientAddressesin interfaceOutboxView
-
setCcRecipientAddresses
-
initializeNextAttemptAt
protected void initializeNextAttemptAt()讓直接建立的待送列沿用 auditing 所寫入的建立時間,避免nextAttemptAt=null導致輪詢器永遠撈不到。Entity callback 於 entity listener 之後執行,因此可安全使用createdDate;若應用未啟用 Spring Data JPA auditing,則明確失敗而非靜默漏送。 -
markSent
-
markSuppressed
標記因政策被抑制(終態,不重試)。用於確定性封鎖,如郵件防火牆全擋——重試無益, 故不增attempts、不排重試,直接轉SUPPRESSED(與DEAD重試耗盡區分)。- Parameters:
error- 抑制原因(自動截斷至MAX_ERROR_LENGTH)
-
recordFailure
記錄一次遞送失敗;依是否逾重試上限轉FAILED(排定重試)或DEAD(放棄)- Parameters:
error- 失敗原因(自動截斷至MAX_ERROR_LENGTH)nextAttemptTime- 下次重試時間(轉 DEAD 時忽略)
-
requeue
重排此列供重送(人工補救入口):把終態 /
SENT/FAILED列重置為PENDING並排定即刻遞送 ——status=PENDING、attempts=0、nextAttemptAt=now、清除lastError與sentAt;maxAttempts不變。重排後回歸正常遞送與退避路徑,可再成功(SENT)或再次耗盡maxAttempts再DEAD(非無限重試),SUPPRESSED政策仍成立則再SUPPRESSED。重排是重排既有列、非新建列:不動
dedupeKey、不涉唯一約束,故不製造重複列。呼叫端於 重排後另行觸發遞送(fast-pathNotificationOutboxDispatcher#dispatchAsync),遞送仍走原子認領、 叢集安全(人工重送與輪詢並發不重複送出)。狀態守衛:
SENDING(認領中):拋ConflictException(對映 HTTP 409)——人工重送不得與進行中遞送競爭; 滯留的SENDING(遞送節點崩潰)由輪詢逾認領逾時後自然重新認領,非本方法路徑。PENDING:no-op(本就待送,不改任何欄位,冪等)。DEAD/FAILED/SUPPRESSED/SENT:重置為PENDING。
- Parameters:
nextAttemptAt- 重新排定的下次嘗試時間點;由應用層的Clock提供- Throws:
ConflictException- 若此列目前為SENDING(認領中)
-