代码之家  ›  专栏  ›  技术社区  ›  Brad Robinson

原子化地使用亚音速活动记录来维护计数器

  •  0
  • Brad Robinson  · 技术社区  · 15 年前

    我正在尝试找出正确的方法来自动递增一个表中的计数器,并将递增的值用作另一个表中记录的伪仅显示ID。

    我有一张公司表和一张工作表。我希望每个公司都有自己的一套工作号码。我确实有一个自动递增的作业ID,但是这些数字是所有公司共享的。例如:每个公司的工作编号一般都应该增加而不留空白。

    IE:

    • 公司(公司ID,下一个工作编号)
    • 工作(公司ID、工作ID、工作编号)

    当前我正在执行此操作(作为分部作业类的方法):

    public void SaveJob()
    {
        using (var scope = new System.Transactions.TransactionScope())
        {
            if (job_id == 0)
            {
                _db.Update<company>()
                    .SetExpression("next_job_number").EqualTo("next_job_number+1")
                    .Where<company>(x => x.company_id == company_id)
                    .Execute();
    
                company c = _db.companies.SingleOrDefault(x => x.company_id == company_id);
    
                job_number = c.next_job_number;
            }
    
            // Save the job
            this.Save();
    
            scope.Complete();
        }
    }
    

    这似乎有效,但我不确定这里是否存在陷阱?只是感觉不对,但我不知道该怎么做。

    谢谢你的建议。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Jürgen Steinblock    15 年前

    第一,

    您应该将TransactionScope与SharedDBConnectionScope结合使用,否则事务将无法按预期工作。

    第二,

    我将使用另一种方法,只需一条语句,而不需要在公司保存工作ID)

    1. 保存作业编号为0的记录

    2. 用这样的东西更新记录

      更新作业集作业编号= (从公司ID=12345的作业中选择max(作业编号)+1) 其中job_id=“+this.job_id;

    (您只需要将此查询转换为子音速语法,我不使用子音速3) 这样可以保证每个公司的作业编号都是唯一的(如果在事务中同时包装save和update命令并使用表锁)。

        2
  •  1
  •   kevinw    15 年前

    在大容量多用户系统上,使用动态代码获取当前最高值可能有风险(可能是重复值)。

    另一种方法是创建一个包含两列的新表;一列是字符pk,另一列是用于存储相关最后一个值的整数。每次需要新值时,请在相关公司的记录中增加该值,并将该值用于订单号。字符pk包含如下内容:

    "LAST_ORDER_NUMBER_COMPANY_" + company_id
    

    我有一个要调用的存储过程,它可以在公司第一次有订单时自动启动一个新记录,也可以为后续订单增加该记录,然后返回新的订单号值。

    推荐文章