此外,真正要解决这个问题,还源于我做的试剂耗材的管理系统。以往生成条码为了保证唯一性,使用日期时间+序列的方式,为了保证它不重复,时间就取的很细,到了毫秒级别。虽然理论上来讲这仍然有重复的可能性。
其实重复毕竟是小概率,但是条码却太长了,比如一个试剂的条码是20140801162430234001,这么一大串,一来不容易被条码枪识别,二来即便识别也容易造成识别前半部分。如果实在没有识别要手输的话,就是要费很大的工夫了。
条码本来就是类似数据库主键的意味,只要保证不重复,就该越短越好。
既然sql server没有序列发生器,那么我们还是用表来做吧。
基本的思路是建立一个有自增ID,时间,序号的表,取每天的该表的序号,每取一次就加一,并且写回该表。那么条码就是日期+序号了。
那么要解决的问题是,如果同时有两个程序都在读取和修改这张表,那该怎么办呢?
一、事务。由于想到事务是sql server里面的排它锁,因此认为只要程序中启用了事务,那么这个问题应该就能够解决,以下是测试的代码:
代码如下 | 复制代码 |
dbquery.sql.clear; end; except |
然后我启动两个程序,同时获取序列,发现有重复。因此得出结论,事务的锁应该仅限于该链接而已。
二、加锁。
那就只能够人工加锁了,把这个表锁住,直到我操作完了,才给别人操作。把上面的sql查询语句改为:
select * from lrm_bar with(TABLOCKX) where datediff(“d”,b_time,getdate())=0
TABLOCKX是sql server中强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个表。直到这个事务提交或者回滚。
之后我再同时测试两个程序同时获取序列:
A:01 03 05 07…
B:02 04 06 08…
OK不会再重复了。
三、条码长度。
解决了序列生成的问题,最后探讨一下条码长度的问题。
由于试剂一天入库数量不超过一千,那么序号就是001-999就足够了;日期的话年取1位,月份和日期各取两位,总共5位。那么生成的条码号就是8位,比原来的一大串短多了。
40801001,如果实在扫描不出,要手输入的话,看一遍就能输入完了,很方便。
序列生成到此完毕,如果你有更好的方法一定要告诉吵吵哦。