亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
什麼是Event Sourcing 和CQRS?
Java 中如何實現(xiàn)?使用Axon Framework
添加依賴(Maven)
示例:銀行賬戶轉(zhuǎn)賬
1. 定義事件
2. 聚合(Aggregate) - 寫模型
3. 事件處理(更新讀模型)
4. 讀模型實體(用於查詢)
5. 查詢接口
何時使用Event Sourcing CQRS?
注意事項
總結(jié)
首頁 Java java教程 Java中的事件採購和CQRS模式

Java中的事件採購和CQRS模式

Jul 29, 2025 am 12:34 AM
java

事件溯源和CQRS適用於復(fù)雜業(yè)務(wù)系統(tǒng),1. 事件溯源通過保存事件序列重建狀態(tài),提供完整審計和時間旅行能力,但增加查詢複雜度;2. CQRS分離讀寫模型,提升擴展性和性能,但引入最終一致性;3. 在Java中可通過Axon Framework結(jié)合Spring Boot實現(xiàn),使用@Aggregate處理命令,@EventSourcingHandler更新狀態(tài),@EventHandler構(gòu)建讀模型;4. 適用於需高審計性、讀寫負(fù)載不均的場景,不適用於簡單CRUD系統(tǒng);5. 注意事件不可變、版本控制、最終一致性處理和調(diào)試複雜性。該架構(gòu)在高要求系統(tǒng)中具有重要價值。

Event Sourcing and CQRS Patterns in Java

事件溯源(Event Sourcing)和命令查詢職責(zé)分離(CQRS)是現(xiàn)代分佈式系統(tǒng)中處理複雜業(yè)務(wù)邏輯和提升系統(tǒng)可擴展性的兩種重要模式。在Java 生態(tài)中,結(jié)合Spring Boot、Axon Framework 等工具,可以高效實現(xiàn)這兩種模式。下面從概念、應(yīng)用場景、實現(xiàn)方式和注意事項幾個方面來解析。

Event Sourcing and CQRS Patterns in Java

什麼是Event Sourcing 和CQRS?

1.事件溯源(Event Sourcing)

傳統(tǒng)系統(tǒng)中,我們通常只保存實體的當(dāng)前狀態(tài)(如用戶餘額為100 元)。而事件溯源的核心思想是:不直接保存狀態(tài),而是保存導(dǎo)致狀態(tài)變化的事件序列。

例如,用戶賬戶的餘額變化不是直接更新balance 字段,而是記錄:

Event Sourcing and CQRS Patterns in Java
  • MoneyDeposited(amount=50)
  • MoneyWithdrawn(amount=20)

狀態(tài)通過重放這些事件來重建。

優(yōu)點:

Event Sourcing and CQRS Patterns in Java
  • 完整審計日誌
  • 易於調(diào)試和回溯
  • 支持時間旅行(重建任意時間點的狀態(tài))

缺點:

  • 查詢性能可能下降(需重放事件)
  • 事件版本管理複雜
  • 初學(xué)門檻較高

2. CQRS(Command Query Responsibility Segregation)

CQRS 將系統(tǒng)的讀寫操作分離:

  • 命令(Command) :修改數(shù)據(jù),對應(yīng)寫模型(Write Model)
  • 查詢(Query) :讀取數(shù)據(jù),對應(yīng)讀模型(Read Model)

這不僅僅是分層,而是允許使用不同的數(shù)據(jù)模型、數(shù)據(jù)庫甚至技術(shù)棧來處理讀寫。

典型結(jié)構(gòu):

 Client → Command → Command Handler → Events → Event Store
                     ↓
               Event Handlers → Update Read Model (eg, SQL, Elasticsearch)
                     ↓
Client ← Query ← Read Model

優(yōu)點:

  • 讀寫模型可獨立優(yōu)化
  • 易於擴展(如讀多寫少場景可橫向擴展查詢服務(wù))
  • 更清晰的職責(zé)劃分

缺點:

  • 系統(tǒng)複雜度上升
  • 讀寫之間存在延遲(最終一致性)

Java 中如何實現(xiàn)?使用Axon Framework

Axon 是Java 中最流行的實現(xiàn)Event Sourcing 和CQRS 的框架,與Spring 集成良好。

添加依賴(Maven)

 <dependency>
    <groupId>org.axonframework</groupId>
    <artifactId>axon-spring-boot-starter</artifactId>
    <version>4.6.0</version>
</dependency>

示例:銀行賬戶轉(zhuǎn)賬

1. 定義事件
public class MoneyDepositedEvent {
    public final String accountId;
    public final double amount;

    public MoneyDepositedEvent(String accountId, double amount) {
        this.accountId = accountId;
        this.amount = amount;
    }
}

public class MoneyWithdrawnEvent {
    public final String accountId;
    public final double amount;

    public MoneyWithdrawnEvent(String accountId, double amount) {
        this.accountId = accountId;
        this.amount = amount;
    }
}
2. 聚合(Aggregate) - 寫模型
@Aggregate
public class BankAccount {

    @AggregateIdentifier
    private String accountId;
    private double balance;

    public BankAccount() {} // Required by Axon

    // Command Handler
    @CommandHandler
    public BankAccount(CreateAccountCommand command) {
        // 發(fā)布賬戶創(chuàng)建事件AggregateLifecycle.apply(new AccountCreatedEvent(command.accountId));
    }

    @CommandHandler
    public void handle(DepositMoneyCommand command) {
        if (command.amount <= 0) {
            throw new IllegalArgumentException("Amount must be positive");
        }
        AggregateLifecycle.apply(new MoneyDepositedEvent(command.accountId, command.amount));
    }

    @CommandHandler
    public void handle(WithdrawMoneyCommand command) {
        if (command.amount > balance) {
            throw new IllegalStateException("Insufficient funds");
        }
        AggregateLifecycle.apply(new MoneyWithdrawnEvent(command.accountId, command.amount));
    }

    // Event Sourcing Handler - 用於更新狀態(tài)@EventSourcingHandler
    public void on(MoneyDepositedEvent event) {
        this.balance = event.amount;
    }

    @EventSourcingHandler
    public void on(MoneyWithdrawnEvent event) {
        this.balance -= event.amount;
    }
}
3. 事件處理(更新讀模型)
 @Component
public class AccountProjection {

    private final AccountRepository accountRepository;

    public AccountProjection(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    @EventHandler
    public void on(MoneyDepositedEvent event) {
        AccountView account = accountRepository.findById(event.accountId)
            .orElse(new AccountView(event.accountId, 0.0));
        account.balance = event.amount;
        accountRepository.save(account);
    }

    @EventHandler
    public void on(MoneyWithdrawnEvent event) {
        AccountView account = accountRepository.findById(event.accountId)
            .orElseThrow();
        account.balance -= event.amount;
        accountRepository.save(account);
    }
}
4. 讀模型實體(用於查詢)
 @Entity
public class AccountView {
    @Id
    private String id;
    private double balance;

    // constructors, getters, setters
}
5. 查詢接口
@RestController
public class AccountQueryController {

    @Autowired
    private AccountRepository accountRepository;

    @GetMapping("/accounts/{id}")
    public AccountView getAccount(@PathVariable String id) {
        return accountRepository.findById(id).orElse(null);
    }
}

何時使用Event Sourcing CQRS?

  • 業(yè)務(wù)邏輯複雜,需要審計追蹤(如金融、訂單系統(tǒng))
  • 讀寫負(fù)載差異大,需要獨立擴展
  • 系統(tǒng)需要支持“撤銷”、“重放”、“時間旅行”
  • 微服務(wù)架構(gòu)中,服務(wù)間通過事件通信

?? 不建議用於簡單CRUD 系統(tǒng),會過度設(shè)計。


注意事項

  • 事件不可變:一旦發(fā)布,不能修改,只能追加補償事件。
  • 事件版本控制:當(dāng)事件結(jié)構(gòu)變化時,需支持序列化兼容或遷移。
  • 讀模型一致性:CQRS 是最終一致,前端需處理“操作成功但查詢未更新”的情況。
  • 調(diào)試難度增加:需要工具支持事件流查看、重放等。

總結(jié)

在Java 中,通過Axon Framework 可以較輕鬆地實現(xiàn)Event Sourcing 和CQRS:

  • 使用@Aggregate管理寫模型
  • @EventSourcingHandler更新聚合狀態(tài)
  • @EventHandler構(gòu)建讀模型
  • 命令和查詢徹底分離

雖然引入了複雜性,但在需要高可審計性、高擴展性的系統(tǒng)中,這種架構(gòu)非常有價值。

基本上就這些,關(guān)鍵在於理解“狀態(tài)是事件的結(jié)果”,以及“讀寫可以走不同的路”。

以上是Java中的事件採購和CQRS模式的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
VSCODE設(shè)置。 JSON位置 VSCODE設(shè)置。 JSON位置 Aug 01, 2025 am 06:12 AM

settings.json文件位於用戶級或工作區(qū)級路徑,用於自定義VSCode設(shè)置。 1.用戶級路徑:Windows為C:\Users\\AppData\Roaming\Code\User\settings.json,macOS為/Users//Library/ApplicationSupport/Code/User/settings.json,Linux為/home//.config/Code/User/settings.json;2.工作區(qū)級路徑:項目根目錄下的.vscode/settings

如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務(wù),必須先關(guān)閉自動提交模式,再執(zhí)行多個操作,最後根據(jù)結(jié)果提交或回滾;1.調(diào)用conn.setAutoCommit(false)以開始事務(wù);2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調(diào)用conn.commit(),若發(fā)生異常則調(diào)用conn.rollback()確保數(shù)據(jù)一致性;同時應(yīng)使用try-with-resources管理資源,妥善處理異常並關(guān)閉連接,避免連接洩漏;此外建議使用連接池、設(shè)置保存點實現(xiàn)部分回滾,並保持事務(wù)盡可能短以提升性能。

在Java的掌握依賴注入春季和Guice 在Java的掌握依賴注入春季和Guice Aug 01, 2025 am 05:53 AM

依賴性(di)IsadesignpatternwhereObjectsReceivedenciesenciesExtern上,推廣looseSecouplingAndEaseerTestingThroughConstructor,setter,orfieldInjection.2.springfraMefringframeWorkSannotationsLikeLikeLike@component@component,@component,@service,@autowiredwithjava-service和@autowiredwithjava-ligatiredwithjava-lase-lightike

Python Itertools組合示例 Python Itertools組合示例 Jul 31, 2025 am 09:53 AM

itertools.combinations用於生成從可迭代對像中選取指定數(shù)量元素的所有不重複組合(順序無關(guān)),其用法包括:1.從列表中選2個元素組合,如('A','B')、('A','C')等,避免重複順序;2.對字符串取3個字符組合,如"abc"、"abd",適用於子序列生成;3.求兩數(shù)之和等於目標(biāo)值的組合,如1 5=6,簡化雙重循環(huán)邏輯;組合與排列的區(qū)別在於順序是否重要,combinations視AB與BA為相同,而permutations視為不同;

故障排除常見的java`ofmemoryError`場景'' 故障排除常見的java`ofmemoryError`場景'' Jul 31, 2025 am 09:07 AM

java.lang.OutOfMemoryError:Javaheapspace表示堆內(nèi)存不足,需檢查大對象處理、內(nèi)存洩漏及堆設(shè)置,通過堆轉(zhuǎn)儲分析工具定位並優(yōu)化代碼;2.Metaspace錯誤因類元數(shù)據(jù)過多,常見於動態(tài)類生成或熱部署,應(yīng)限制MaxMetaspaceSize並優(yōu)化類加載;3.Unabletocreatenewnativethread因係統(tǒng)線程資源耗盡,需檢查線程數(shù)限制、使用線程池、調(diào)整棧大?。?.GCoverheadlimitexceeded指GC頻繁但回收少,應(yīng)分析GC日誌,優(yōu)化

Python Pytest夾具示例 Python Pytest夾具示例 Jul 31, 2025 am 09:35 AM

fixture是用於為測試提供預(yù)設(shè)環(huán)境或數(shù)據(jù)的函數(shù),1.使用@pytest.fixture裝飾器定義fixture;2.在測試函數(shù)中以參數(shù)形式註入fixture;3.yield之前執(zhí)行setup,之後執(zhí)行teardown;4.通過scope參數(shù)控製作用域,如function、module等;5.將共用fixture放在conftest.py中實現(xiàn)跨文件共享,從而提升測試的可維護性和復(fù)用性。

了解Java虛擬機(JVM)內(nèi)部 了解Java虛擬機(JVM)內(nèi)部 Aug 01, 2025 am 06:31 AM

TheJVMenablesJava’s"writeonce,runanywhere"capabilitybyexecutingbytecodethroughfourmaincomponents:1.TheClassLoaderSubsystemloads,links,andinitializes.classfilesusingbootstrap,extension,andapplicationclassloaders,ensuringsecureandlazyclassloa

如何使用Java的日曆? 如何使用Java的日曆? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當(dāng)前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應(yīng)優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

See all articles