【问题标题】:Generate Sequential Invoice Number in a Multiuser Web Environment在多用户 Web 环境中生成顺序发票编号
【发布时间】:2017-11-09 08:34:42
【问题描述】:

我尝试使用网络表单创建和打印发票。我正在尝试找到我应该使用的最佳推荐做法。 到目前为止,我的做法是;

  1. 创建一个存储“下一个发票编号”的表,然后使用存储过程生成下一个编号,例如“下一个编号”+1。

  2. 将之前的数字存储在发票数据库表中,然后在我的 c# 代码中将其加一。

我想避免的是使用 SQL Server 标识(自动增量)来生成发票编号,因为可能会发生差距(我在现实生活中看到会发生),但也有文章提到这些差距。 Why are there gaps in my IDENTITY column values? Identity increment is jumping in SQL Server database

我的问题是我应该遵循什么建议做法来确保每张发票都会获得顺序唯一的发票编号?

【问题讨论】:

  • 只是为了清除任何XY Problem 问题,您想通过使用顺序发票编号来实现什么?实际上,我会说使用顺序发票编号本身并不是一个好习惯。如果这些数字显示在外部,那么您的任何客户都可以知道您生产了多少张发票。或者,也许您实际上想要每个客户的序列号?
  • 方法“a)”有什么问题?你遇到过问题吗?方法“a)”的“现代”实现将使用SEQUENCE,但我不会费心重写现有代码。
  • Pac0,存在要求系统生成连续发票编号的法律问题。另外,我不是在要求代码...我在询问推荐的方法。我也相信实践 a) 更好
  • 如果您并行创建发票(我假设是这种情况),则无法 100% 可靠地防止出现空白。您当然可以在插入发票时锁定整个表格,但我认为这对您来说不是一个好的解决方案(另一方面,如果您的负载很小并且不经常创建发票 - 为什么不)。如果“无间隙”要求不是非常严格的要求(如您所在国家/地区的某些法律),那就别管它了。
  • @Alex 我并没有质疑他对他的实际问题进行研究的事实。他做到了,这个问题很好。我只是想确保他试图解决的潜在问题实际上需要使用序列号。 OP已经澄清了(法律要求),所以这绝对不是XY问题。

标签: c# asp.net sql-server entity-framework


【解决方案1】:

我会推荐方法“a)”。

它有两种变体:

  1. 使用SEQUENCE。确保指定了 NO CACHE 选项。
  2. 如您所述,创建一个“计数器”表,用于存储要分配的下一个 ID。

它的代码如下所示:

CREATE TABLE Counter( NextID INT NOT NULL DEFAULT(1))
INSERT INTO Counter VALUES( DEFAULT )

DECLARE @NextID INT
UPDATE Counter
SET @NextID = NextID,
    NextID = NextID + 1

SELECT @NextID

注意:我不完全理解您对选项“b)”的描述。假设您的意思是:您想搜索当前发票表以查找 MAX 现有发票,然后向其中添加一张,那么我强烈建议您不要使用这种方法,因为它很脆弱。如果您不为搜索查询创建覆盖索引,则可能会因竞争条件而出现问题。

【讨论】:

  • 感谢您的回答。我的问题是:序列中是否有可能存在间隙?你相信如果我没有缓存它会消除差距吗?我之所以问,是因为在这篇文章中,我在答案中看到可能存在差距(因为缓存......)。 stackoverflow.com/questions/16472431/sql-server-sequence-gaps
  • @focus 仍然可能存在差距,每次交易失败。您获取价值 X,试图插入具有该价值的发票,无论出于何种原因,交易都失败了 - 现在您有一个缺口,因为 X 将不再被使用。
  • 唯一可能产生间隙的明显情况是事务失败并回滚时。我可以看到您可以避免这种情况的唯一方法是使用带有“计数器”表的可序列化事务。注意:它会引入大量的锁定和阻塞,并且会损害性能。您仍然需要进行大量广泛的测试(包括从计算机上拔下电源线)以确认它在所有情况下都能正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多