DDD:聚合根的批量刪除是不是可以批量傳送請求

weixin_34279184發表於2013-06-01

背景

搞了近五年的系統開發,總是抱著一種思維模式,使用者的一個操作對應一個請求和一個事務,比如:使用者選擇了N條記錄,我就會向伺服器發生一個請求,伺服器在一個事務中進行處理。前幾天在群裡一個前輩反問:批量操作難道真的要在一個事務中?這個問題讓陷入了反思,謝謝前輩們(魏瓊東)。

DDD中有聚合的概念,一個聚合有且只有一個聚合根和一些其他實體,如:訂單聚合中,訂單是聚合根,訂單明細是聚合內的實體。因為DDD中只能操作聚合根,這篇文章就介紹聚合根的批量刪除問題。有人問聚合內的實體的刪除咋弄?聚合內實體的刪除必須伴隨著聚合根的修改(這裡不做詳細介紹)。

另外一點是需要注意的是,引入工作單元之後,批量操作和單個操作伺服器端的邏輯是不同的,如:索引驗證問題和工號生成問題(這裡不做詳細介紹)。

批量刪除思路

我目前有三種選擇,我記錄下來,然後一個一個分析:

  1. 傳送一個請求,伺服器一個事務。
  2. 傳送一個請求:伺服器N個事務。
  3. 傳送N個請求,伺服器N個事務。

傳送一個請求,伺服器一個事務。

這是我之前採用的思路,現在覺得非常不好,為什麼非要在一個事務中呢?如果您覺得非要在一個事務中,就告訴我一聲。

傳送一個請求:伺服器N個事務。

這種思路可以接受,不過要在伺服器端做額外的處理,如:收集哪些失敗或成功的資訊,發生給客戶端,如果我不用AJAX,我就會選擇這個方案。

傳送N個請求,伺服器N個事務。

考慮到我是AJAX程式設計,這種思路好,重分利用了客戶端。

傳送N個請求,伺服器N個事務的實現思路

思路有了,實現就不是問題了,搞個佇列排隊傳送請求就行了,當然你可以選擇並行傳送請求或分批次排隊傳送請求。

刪除的客戶端邏輯

 1 /**
 2  * 刪除功能。
 3  * 
 4  * @class Delete
 5  * @extends Happy.action.Action
 6  * @namespace Happy.table.action
 7  */
 8 Ext.define('Happy.table.action.Delete', {
 9     extend: 'Happy.action.Action',
10     requires: [
11         'Happy.server.PessimisticLockProxy',
12         'Happy.Msg',
13         'Happy.Ajax'
14     ],
15 
16     DELETE_CONFIRM_TITLE: '刪除確認',
17     DELETE_CONFIRM_MSG: '確定執行刪除嗎?',
18 
19     defaultConfig: {
20         itemId: 'delete',
21         iconCls: 'delete-button',
22         text: '刪除',
23         disabled: true,
24         autoEnableAndDisable: true
25     },
26 
27     /**
28      * 契約:<br/>
29      * <ul>
30      *  <li>button.up('tablepanel')!==null。</li>
31      * </ul>
32      * @protect
33      * @method onClickHandler
34      * @param {Ext.button.Button} button 按鈕
35      */
36     onClickHandler: function (button) {
37         var me = this;
38 
39         var table = button.up('tablepanel');
40         var records = table.getSelection();
41 
42         if (records.length == 0) {
43             return;
44         }
45 
46         Ext.Msg.confirm(me.DELETE_CONFIRM_TITLE, me.DELETE_CONFIRM_MSG, function (btn) {
47             if (btn !== 'yes') {
48                 return;
49             }
50 
51             me.deleteRecords(records);
52         });
53     },
54 
55     /**
56      * private
57      * @method deleteRecords
58      */
59     deleteRecords: function (records) {
60         var me = this;
61 
62         if (records.length == 0) {
63             Happy.Msg.showDeleteSuccess();
64             return;
65         }
66 
67         Happy.Ajax.destroy(records.shift(), {
68             success: function (record) {
69                 me.deleteRecords(records);
70             },
71             failure: function (record, operation) {
72                 Happy.Msg.showDeleteFailure(operation.error);
73             }
74         });
75     }
76 });

刪除的伺服器端邏輯

 1         /// <summary>
 2         /// 刪除。
 3         /// </summary>
 4         public ActionResult Delete(TAggregateRoot item)
 5         {
 6             this.CurrentCommandService.Execute(new TDeleteCommand
 7             {
 8                 Aggregate = item
 9             });
10 
11             return this.NewtonsoftJson(new
12             {
13                 success = true
14             });
15         }

效果圖

備註

這裡只是演示了批量刪除,有很多針對聚合根的批量操作都可以這麼處理。

 

相關文章