❤️‍🔥 Solon Cloud Event 新的事務特性與應用

1、Solon Cloud Event?

是 Solon 分佈式事件總線的解決方案。也是 Solon “最終一致性”分佈式事務的解決方案之一

2、事務特性

事務?就是要求 Event 有原子性,當多個 Event 發佈時,要麼全成功,要麼全失敗。

public class EventDemo {
    public void event_tran() {
        //新建一個 Event 事務
        EventTran eventTran = CloudClient.event().newTran();

        try {
            //發佈,並使用事務
            CloudClient.event().publish(new Event("user.event1", "test1").tran(eventTran));
            CloudClient.event().publish(new Event("user.event2", "test2").tran(eventTran));
            CloudClient.event().publish(new Event("user.event2", "test3").tran(eventTran));

            //如果沒問題,提交事務
            eventTran.commit();
        } catch (Throwable ex) {
            //如果有問題,回滾事務
            eventTran.rollback();
        }
    }
}

上面的體驗與經典的 Jdbc 事務是很像的。加入 Solon 的事務註解管理後,體驗可以再簡潔些,也能與 Jdbc 事務整合到一起。

@Component
public class EventDemo {
    //使用 @Tran 管理事務(將 jdbc, event 事務整合到一起)
    @Tran
    public void event_and_jdbc_tran() {
        //新建一個 Event 事務,並加入 @Tran 的管理
        EventTran eventTran = CloudClient.event().newTranAndJoin(); 

        CloudClient.event().publish(new Event("user.event1", "test1").tran(eventTran));
        CloudClient.event().publish(new Event("user.event2", "test2").tran(eventTran));
        CloudClient.event().publish(new Event("user.event2", "test3").tran(eventTran));
    }
}

3、擬模真實的場景應用:

我們設計一個用戶註冊的場景應用:

  • 持久層添加用戶記錄
  • 註冊後發佈一個已註冊事件;再發佈一個10天后觸發的已喚醒事件
  • 在已註冊事件裏,我們給用戶送10個金幣;再送手機100元衝值
  • 在已喚醒事件裏,我們檢查用戶的活動行爲;如果有,再送100個金幣(作爲獎勵);如果沒發推送,告知有抽獎

主服務程序,負責主業務:

@Component
public class UserService {
    @Inject
    UserDao userDao;
    
    //用戶註冊
    @Tran
    public void userRegister(long userId, String name){
        userDao.addUser(userId, name);
        this.onUserRegistered(userId);
    }
    
    //當用戶完成註冊時(發佈事件)
    private void onUserRegistered(long userId) {
        String eventJson = String.format("{\"userId\":%d}", userId);
        Date  eventTime = DateTime.Now().addDay(10);
        
        EventTran eventTran = CloudClient.event().newTranAndJoin();
        
        //發佈用戶已註冊事件
        CloudClient.event().publish(new Event("user.registered", eventJson).tran(eventTran));
        //發佈用戶已喚醒事件(用於檢查用戶在10內,有沒有活動行爲)
        CloudClient.event().publish(new Event("user.reawakened", eventJson).scheduled(eventTime).tran(eventTran));
    }
}

次服務程序,負責輔助業務(也可以合到主服務程序):

@CloudEvent("user.registered")
public class UserRegisteredEventHandler implements CloudEventHandler {
    @Inject
    UserService userService;
    @Inject
    MobileService mobileSerivce;
    
    @Override
    public boolean handler(Event event) throws Throwable {
        long userId = ONode.load(event.context()).get("userId").getLong();
        
        //送10個金幣
        userService.addGold(userId, 10);
        
        //送手機充值100塊
        String mobie = userService.getMobile(userId);
        mobileSerivce.recharge(mobile, 100);
        
        return true;
    }
}

@CloudEvent("user.reawakened")
public class UserReawakenedEventHandler implements CloudEventHandler {
    @Inject
    UserService userService;
    @Inject
    PushService pushService
    
    @Override
    public boolean handler(Event event) throws Throwable {
        long userId = ONode.load(event.context()).get("userId").getLong();
        
        if (userService.hasLive(userId, 10)) {
            //再送100個金幣
            userService.addGold(userId, 100);
        } else {
            //獲取設備id
            String duid = userService.getDuid(userId);
            //發佈推送
            pushService.push(duid, "有100個金幣等你來拿喲...")
        }
        
        return true;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章