• DDD:聚合根的批量删除是不是可以批量发送请求


    背景

    搞了近五年的系统开发,总是抱着一种思维模式,用户的一个操作对应一个请求和一个事务,比如:用户选择了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         }

    效果图

    备注

    这里只是演示了批量删除,有很多针对聚合根的批量操作都可以这么处理。

  • 相关阅读:
    hibernate的dialect大全
    jdbc.properties 链接各类数据库的基本配置以及URL写法
    Springboot中redis的学习练习
    博客开通了
    Java String类的hashCode()函数
    Java String类中CaseInsensitiveComparator.compare()方法的实现
    git pull远程所有分支
    Python的权限修饰符
    Tmux快捷键
    __future__模块
  • 原文地址:https://www.cnblogs.com/happyframework/p/3111778.html
Copyright © 2020-2023  润新知