【发布时间】:2020-08-25 08:29:02
【问题描述】:
我有一个关于为下面的新发票生成发票编号的简单示例:
// API generate invoice number
public void PublishInvoice(Object invoiceData)
{
lock (companyInfo) // (1) if request is the same company will be blocked
{
int invoiceNo = GetNextNo(); // (2) get new invoice number from database (next no = current no + 1)
invoiceData.InvoiceNo = invoiceNo; // (3) set invoice number to invoice data
Save(invoiceData); // (4) save invoice data to database
}
}
我遇到的问题是如果两个请求同时调用这个API,第二个请求会在(1)处被阻塞,当第一个请求完成执行(4之后)然后第二个请求执行(2)获取下一张发票编号,但第一个请求的发票尚未保存到数据库中,因此第二个发票与第一个发票的发票编号相同。
我的问题是如何处理这个问题。我在数据库中阻塞时对性能感到焦虑(我考虑触发器或约束或事务)
附加:我创建了一个触发器,它会在创建新发票之前触发,它会检查发票号码是否已经可用,并且它有效,但我希望会有一个更好的解决方案(基于可用性技术),b/c 我不想检查每个插入请求。
【问题讨论】:
-
那是什么数据库系统?大多数 SQL 数据库都提供了一种自动增加列的方法。
-
还有:
GetNextNo是如何实现的?如果您有某种“序列”,这应该不是问题,它将具有原子“增量和获取”功能。 -
我使用 SQL Server 数据库。我不能使用自动增量,因为发票编号取决于其他一些字段。有了sequence,当你调用sequence,生成下一个数字,但是这个事务失败了,sequence不会回滚,我的业务会出错。
-
我明白了。我认为在这种情况下,您会遇到包括创建发票编号和插入在内的事务。
-
是的,如果出现问题,将不会创建发票和发票编号
标签: c# database transactions synchronization locking