我使用Max功能生成发票编号,并在最后一个发票编号上加1。非常直截了当。但我将此应用于多用户环境中遇到问题。因为两个用户同时打开发票窗口都可以获得相同的ID,发票号码应该是第一个出现而不是最后一个,所以我不能使用身份(自动生成ID)作为发票号码。我想在C#...
中为多用户环境窗口表单生成发票编号另一个问题是两个用户同时访问和更新同一记录会发生什么。
我希望你能理解这个问题。我读到了乐观与悲观锁定,但我需要一个解决方案。那么有人可以回复我吗
答案 0 :(得分:3)
有一个不同的数据库表,它将存储最大发票号。 当用户打开发票窗口时,运行存储过程:
这将确保即使有同时请求,您也将始终获得唯一的发票号。
反面: 1.此存储过程不能同时为多个用户运行,因此在高流量的情况下它将成为瓶颈。 2.发票号码上会有漏洞 - 发票被取消的漏洞。
如果您对此方法不满意,那么必须在保存时生成发票编号,这将是IDENTITY
列,但您已提到用户希望在开始时查看发票编号在发票上工作。
更新
我找到了一篇很好的文章,用sp_getapplock
详细阐述了上述方法。文章链接为HERE。我建议使用这种方法。
答案 1 :(得分:1)
一般来说问题是你的应用程序提出了不好的要求,而且方法也不合适。
创建发票以进行编辑时,不应分配发票编号,而是将其发送到系统进行交易。这样一来,中止就不会留下空白。
收集发票明细,然后通过存储过程创建插入,将正确的锁定到位。这是微不足道的 - 如果你知道如何锁定相关的表,或者使用app锁定这个SP。
通常,这是存储过程有意义的少数几个地方之一。使用0个订单项生成非帐单发票,以便您的应用程序可以添加详细信息。瞧,问题解决了。如果用户中止,请将发票标记为“已取消”并完成。
答案 2 :(得分:-1)
自动增量列是最佳解决方案。这就是我们在SQL Server中称为Identity列的内容。
如果在您的情况下您无法使用它,您可以在服务器端代码中创建一个线程安全的方法,以根据静态属性生成发票ID。 确保您在单实例模式下使用服务。
static long invoiceId = getMaxFunction();
...
...
public long GenerateInvoiceId()
{
lock(this)
{
return invoiceId++;
}
}