我正在尝试找出在一个表中以原子方式递增计数器的正确方法,并将该递增的值用作另一个记录中的伪显示ID。
我拥有的是公司表和工作表。我希望每家公司都拥有自己的job_numbers。我有一个自动增量job_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();
}
}
它似乎有用,但我不确定这里是否有陷阱?这只是感觉不对,但我不确定如何做到这一点。
任何建议表示赞赏。
答案 0 :(得分:1)
首先,
您应该将TransactionScope与SharedDbConnectionScope结合使用,否则您的交易将无法按预期运行。
其次,
我会使用另一种方法使用单个语句,而无需将job_id保存到公司中)
使用job_number = 0保存记录
使用类似的内容更新记录
UPDATE JOBS SET JOB_NUMBER = (SELECT MAX(job_number)+1 FROM JOBS WHERE company_id = 12345) WHERE job_id =“+ this.job_id;
(你只需要将此查询转换为亚音速语法,我不使用subsonic3) 这应该保证每个公司的作业号都是唯一的(如果你在事务中包装save和update命令并使用表锁)。
答案 1 :(得分:1)
在高容量多用户系统上使用动态代码获取当前最高值可能存在风险(潜在的重复值)。
另一种方法可能是创建一个包含两列的新表;一个字符PK,另一个整数来存储相关的最后一个值。每次需要新值时,请增加相关公司记录中的值,并将该值用于订单号。角色PK包括:
"LAST_ORDER_NUMBER_COMPANY_" + company_id
我有一个存储过程来调用,它会在公司第一次订购时自动启动新记录,或者为后续订单增加新记录,然后返回新的订单号值。