我需要以快速可靠的方式生成唯一且连续的数字(用于发票).目前使用Oracle序列,但在某些情况下,由于可能发生的异常,生成的数字不连续.
我想了几个解决方案来解决这个问题,但他们都没有说服我.你推荐什么解决方案?
使用select max()
SELECT MAX (NVL (doc_num, 0)) +1 FROM invoices
Run Code Online (Sandbox Code Playgroud)使用表格存储为发票生成的最后一个数字.
UPDATE docs_numbers
SET last_invoice = last_invoice + 1
Run Code Online (Sandbox Code Playgroud)另一种方案?
正如他所建议的那样,你应该真正回顾"无间隙"要求的必要性
如果事务使用序列号但随后回滚,则会出现间隙。
也许答案是在发票无法回滚之前不要分配发票号码。这可以最大限度地减少(但可能不会消除)出现间隙的可能性。
我不确定是否有任何快速或简单的方法来确保序列中没有间隙 - 扫描 MAX,添加一个,然后插入可能是最接近安全的,但出于性能原因(以及并发困难)不建议这样做)并且该技术不会检测是否分配了最新的发票编号,然后删除并重新分配。
您能否以某种方式解释差距 - 通过识别哪些发票号码已“使用”但“未永久”以某种方式?自主交易可以帮助做到这一点吗?
另一种可能性——假设差距相对较小且相距较远。
创建一个表来记录序列号,在获取新序列值之前必须重用这些序列号。通常,它是空的,但是每分钟、每小时、每天运行的某个进程会检查间隙并将丢失的值插入到该表中。所有进程首先检查缺失值表,如果存在任何值,则使用其中的值,经历更新表并删除它们使用的行的缓慢过程。如果表为空,则获取下一个序列号。
不太令人愉快,但是“开具发票号码”与“扫描缺失值”的分离意味着,即使某些线程在使用缺失值之一时开票过程失败,该值也会被重新发现为缺失,并且下次重新发布 - 重复直到某个过程成功为止。
归档时间: |
|
查看次数: |
9807 次 |
最近记录: |