業(yè)務(wù)系統(tǒng)記錄操作日志的幾種方式

最近的一個(gè)業(yè)務(wù)系統(tǒng),需要實(shí)現(xiàn)一套操作日志的記錄方式。這篇日志算是對(duì)各種實(shí)現(xiàn)的一個(gè)思考翩剪。

一 每個(gè)操作記錄流水
這種方式非常適合每一步操作都非常重要的系統(tǒng)。比如常見的金融操作系統(tǒng)饶氏。在一般的場(chǎng)景下,我們只會(huì)對(duì)涉及金錢的操作記錄這種流水日志有勾,比如轉(zhuǎn)賬疹启,扣款等。
在設(shè)計(jì)賬戶流水表的時(shí)候蔼卡,需要有以下幾個(gè)必須的字段:
(1) instruction_id 流水號(hào)
(2) amount 金額
(3) operation_type 操作類型(轉(zhuǎn)賬or扣款)
(4) before_balance 操作前賬戶余額
(5) after_balance 操作后賬戶余額
(6) time 操作時(shí)間
第一個(gè)字段喊崖,流水號(hào),是主鍵雇逞。這個(gè)字段的必要性在于荤懂,它能維護(hù)該記錄修改的冪等性。簡(jiǎn)單的實(shí)現(xiàn)塘砸,流水號(hào)可以使用uuid节仿。
當(dāng)前端發(fā)起一個(gè)充值的操作時(shí),首先在前端產(chǎn)生一個(gè)流水號(hào)掉蔬,然后將其他的用戶填寫的參數(shù)通過(guò)rpc請(qǐng)求發(fā)送到后端廊宪。后端的處理流程如下:
(1) 開啟事務(wù)
(2) 從db中查詢賬戶余額
(3) 修改賬戶余額
(4) 記錄流水
(5) 提交事務(wù)
假設(shè)在執(zhí)行過(guò)程中,出現(xiàn)了網(wǎng)絡(luò)問題女轿,該執(zhí)行結(jié)果處于未知狀態(tài)箭启,那么前端可以通過(guò)剛才的uuid反復(fù)重試,直到得到一個(gè)確定的結(jié)果為止蛉迹。
我們可以對(duì)流水表稍做改進(jìn)傅寡,以適應(yīng)普遍的情況。字段如下:
(1) instruction_id 流水號(hào)(在對(duì)可靠性要求不太高的場(chǎng)景下婿禽,可使用數(shù)據(jù)庫(kù)自增id)
(2) operation_type 操作類型
(3) before (一個(gè)json赏僧,描述修改前的該行記錄)
(4) after (json, 描述修改后的該行記錄)
(5) time
還有一些可選的字段大猛,比如 input_param(輸入?yún)?shù))扭倾,操作人等等。
這種基于流水的方式優(yōu)點(diǎn)有:
1 可靠性很高
2 實(shí)現(xiàn)方式確定挽绩,可以基于接口做注解實(shí)現(xiàn)
3 可以基于該流水膛壹,實(shí)現(xiàn)業(yè)務(wù)層的操作回滾
但是它的缺點(diǎn)也很明顯:
1 增加開發(fā)量,需要額外增加記錄寫入
2 降低運(yùn)行效率,需要多一到兩次查詢(before, after)
3 和業(yè)務(wù)綁定的比較緊

二 基于數(shù)據(jù)庫(kù)的binlog實(shí)現(xiàn)
第二種方式是基于mysql的binlog來(lái)實(shí)現(xiàn)模聋。這種方式最大的好處是可以和業(yè)務(wù)完全的解耦肩民,而且統(tǒng)計(jì)的結(jié)果是完全準(zhǔn)確的(相比于有些完全基于業(yè)務(wù)代碼的實(shí)現(xiàn)來(lái)說(shuō),這類實(shí)現(xiàn)一般是對(duì)執(zhí)行前后查詢兩次)链方。
關(guān)于binlog的定義及獲取持痰,可以參考

http://www.reibang.com/p/1f7889273845

binlog可以描述為下面這種model:

@Data
public class RowDiffModel {
    long timestamp;
    String tableName;
    List<String> pkColumnName = new ArrayList<>();  //主鍵列
    List<Object> pk = new ArrayList<>();
    int type;  //1 新建 //2 更新 //3 刪除
    List<String> diffColumns = new ArrayList<>();
    Map<String, Object> preValue = new HashMap<>();
    Map<String, Object> newValue = new HashMap<>();
}

基于binlog的實(shí)現(xiàn)還有一個(gè)小問題。如何獲得用戶的操作id祟蚀?在一些涉及權(quán)限授權(quán)及權(quán)限分離的系統(tǒng)中工窍,操作id非常重要。但由于這個(gè)字段完全隸屬于業(yè)務(wù)層前酿,和數(shù)據(jù)庫(kù)的設(shè)計(jì)關(guān)聯(lián)度并不大患雏。
為了解決這個(gè)問題,我們需要在每個(gè)涉及用戶操作的表中增加一個(gè)新的字段operator_id罢维。
還有一種情況是淹仑,用戶的某一步操作涉及多個(gè)表的修改,這個(gè)時(shí)候可以按事務(wù)id將binlog聚集起來(lái)肺孵。
之后匀借,我們需要將binlog轉(zhuǎn)換為一條操作記錄,記錄到庫(kù)里平窘,操作記錄的字段如下:
(1) operator_id (操作人id)
(2) operation_type (操作類型怀吻,可根據(jù)表及binlog類型(insert,update初婆,delete)確定)
(3) before (一個(gè)json蓬坡,描述本行記錄修改前的值)
(4) after (描述本行記錄修改后的值)
(5) timestamp (時(shí)間戳)

現(xiàn)在,用戶操作日志的生成及查詢磅叛,整體流程如下:
1 用戶操作修改表
2 開啟異步服務(wù)獲取binlog
3 根據(jù)事務(wù)id將binlog做一定的聚合處理
4 將binlog轉(zhuǎn)換為一條原始的操作日志屑咳,并記錄到庫(kù)里
5 當(dāng)用戶查詢操作日志時(shí),根據(jù)條件檢索操作日志
6 將操作日志轉(zhuǎn)換為一個(gè)用戶可讀的view返回

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弊琴,一起剝皮案震驚了整個(gè)濱河市兆龙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌敲董,老刑警劉巖紫皇,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腋寨,居然都是意外死亡聪铺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門萄窜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)铃剔,“玉大人撒桨,你說(shuō)我怎么就攤上這事〖担” “怎么了凤类?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)普气。 經(jīng)常有香客問我谜疤,道長(zhǎng),這世上最難降的妖魔是什么现诀? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任茎截,我火速辦了婚禮,結(jié)果婚禮上赶盔,老公的妹妹穿的比我還像新娘企锌。我一直安慰自己,他們只是感情好于未,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布撕攒。 她就那樣靜靜地躺著,像睡著了一般烘浦。 火紅的嫁衣襯著肌膚如雪抖坪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天闷叉,我揣著相機(jī)與錄音擦俐,去河邊找鬼。 笑死握侧,一個(gè)胖子當(dāng)著我的面吹牛蚯瞧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播品擎,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼埋合,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了萄传?” 一聲冷哼從身側(cè)響起甚颂,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秀菱,沒想到半個(gè)月后振诬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡衍菱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年赶么,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梦碗。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡禽绪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洪规,到底是詐尸還是另有隱情印屁,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布斩例,位于F島的核電站雄人,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏念赶。R本人自食惡果不足惜础钠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叉谜。 院中可真熱鬧旗吁,春花似錦、人聲如沸停局。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)董栽。三九已至码倦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锭碳,已是汗流浹背袁稽。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留擒抛,地道東北人推汽。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像歧沪,于是被迫代替她去往敵國(guó)和親民泵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容