我需要以一种快速,可靠的方式生成唯一且连续的数字(用于发票)。我当前使用的是Oracle序列,但是在某些情况下,由于可能发生的异常,生成的数字为,而不是连续的。
我以为可以解决此问题的解决方案有两个,但都没有一个令我信服。您推荐什么解决方案?
SELECT MAX (NVL (doc_num, 0)) +1 FROM invoices
UPDATE docs_numbers
SET last_invoice = last_invoice + 1
最佳答案
如果事务使用序列号,但随后回滚,则会出现间隙。
也许答案是在发票无法回滚之前不分配发票号。这样可以最小化(但可能不会消除)间隙的可能性。
我不确定是否有任何快速或简便的方法来确保序列中没有间隙-扫描MAX,添加一个,然后插入可能最接近安全的序列,但是出于性能原因(以及并发困难)不建议使用),该技术将不会检测是否已分配了最新的发票编号,然后将其删除并重新分配。
您能以某种方式解决差距吗?通过识别以某种方式“使用过”但未将其永久化的发票编号?自主交易可以帮助做到这一点吗?
另一种可能性-假设差距相对较小且相差很大。
创建一个表,该表记录在获取新序列值之前必须重新使用的序列号。通常,它是空的,但是某些进程每隔……分钟,小时,天……运行一次,以检查间隙并将缺失的值插入此表中。所有进程都首先检查遗漏值表,如果存在遗漏值,请从那里使用一个值,经历更新表并删除它们使用的行的缓慢过程。如果表为空,则获取下一个序列号。
这不是很令人愉快,但是“发出发票号”与“扫描缺失值”的解耦意味着即使使用某些缺失值的某个线程的发票处理失败,该值也将被重新发现并丢失。下次重新发布-重复进行直到成功。