关于业务编号相关问题
在开发中业务编号问题恐怕是最常见的了,比如如何编号,编号如何使用,还有如何保证并发的效率并且不重复。
首先是如何编号,其实关于业务编号最常见的误解是必须严格遵守一定的编号规则,编号中各个部分都有严格的含义,从编号中可以看出一些内容来。实际上也是如此,业务人员对于编号的要求比研发人员要高,有时很依赖编号规则。不过呢,因为随着业务的变化特别是时间的推移,有时业务编号不再能严格遵守当时的含义,比如我们在某类业务编号中增加了机构编号部分,表示所属机构,一看就知道是那个机构的,不过机构也是会变化调整的,分分合合是正常的,因此有时一些编号不再能够代表现在的机构了,但是不太了解这些的业务人员有时候就会有疑问。只能说,这个编号中的机构编号部分代表的是当时创建时的机构,而非现在的机构。另外常见的业务编号一般都是固定长度,其中包含一项特多含义的字符,有的还包括年度信息,各类编号公共的部分基本上是流水号了,如何生成流水号是一个比较难以说清楚的,方案也挺多,适用不同场景。
业务编号除了遵守一定的规则之外,以便还有其他特定的要求,比如编号唯一、编号连续等,其实要做到这些不太容易,特别是针对使用频率高、并发高的情况更是如此。一般说来,大家会使用一些类似编号生成器的小工具,我们也自己设计了一个,不过使用中还是出现过不少问题,值得注意。首先保证编号唯一,相对来说可以使用数据库的唯一约束进行硬约束,不会产生重复的问题,但是前提要满足效率问题,避免并发时产生锁,生成一个编号尽量时间短,如有可能不要和具体业务逻辑在一个事务中(因为生成编号相对容易,但是有时业务逻辑比较复杂,需要的时间窗口可能较大)。如果业务并不要求编号连续,我们及时跳过一些编号也无所谓,这样可以避免锁问题和效率问题,这个是要争取的。当然也有些情况非得连续编号,这就有些难了,有时候分组情况下的组内连续(多个编号组,组内流水号连续)不失是一个变通的办法,因为避免锁和提高效率还是很重要的。当然如果业务上并发少是最好的,这样你基本上都可以满足,不用考虑太多。
还有就是避免使用对现有生成的所有编号取最大值加1的获取编号方法(这种方法随着时间的迁移越来越有效率问题),可以借用oracle的sequence,但是要注意RAC和缓存导致的顺序或者跳号问题。