帮帮忙,如何获取唯一值?

时间:2021-11-05 08:52:49
我想问一下,如果我同时多个用户对一个表操作,目的是获取一个流水帐号,我的表里始终只存放一条数据(一个流水帐号)我的流水帐号是以系统时间+序号生成的如(20040909+0001、20040909+0002)
生成的过程是:每次都查询数据库里是否有当天时间记录的流水帐号,如果有提取出来update它加1,如果没有则删除原来的记录,插入一条如:200409100001
我需要如果多个人同时操作他,保证每个人能获取唯一的流水帐号应该怎样做;
我写的代码如下:但没有考虑到如果同时多人操作的话会有人取得相同流水帐号的可能,问应该如何修改

                  $year  = date( "Y", mktime()) ;//当前系统时间的年分2004
$month = date( "m", mktime()) ;//月
$day   = date( "d", mktime()) ;//日
$strdate   = $year.$month.$day;
$query="select * from tb_tradenum";
$db->query($query);
if ($db->nf()){
$db->next_record();
$dealnum_tmp =$db->f(fd_trade_num);
$strdate_tmp =substr($dealnum_tmp,0,8);
$strnum =substr($dealnum_tmp,8);
}
if($strdate==$strdate_tmp){
$strnum++;
if($strnum<10){
$dealnum=$strdate."0000".$strnum;
}elseif($strnum<100){
$dealnum=$strdate."000".$strnum;
}elseif($strnum<1000){
$dealnum=$strdate."00".$strnum;
}elseif($strnum<10000){
$dealnum=$strdate."0".$strnum;
}elseif($strnum<100000){
$dealnum=$strdate."".$strnum;
}
$query="update tb_tradenum set fd_trade_num='$dealnum'";
$db->query($query);
}else{
$query="delete from tb_tradenum";
$db->query($query);
$dealnum=$strdate."00001";     //流水号
$query="insert into tb_tradenum (fd_trade_num) values ('$dealnum')";
$db->query($query);
}

6 个解决方案

#1


1。创建序列
  create sequence SEQNAME
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;
2。使用序列
20040909+0001------〉'20040909'||SEQNAME.NEXTVAL

#2


我看不懂你的代码。
我一般这样处理  select * from tb_tradenum for update nowait
将纪录锁上。

#3


我的过程是
查询表获取数据,然后对数据分析;从而进行update表,或删除旧的,添加新的

如果将纪录锁上了,那怎么样把他解开呢,在没解锁前其他用户一直等待吗?
commit?在代码里怎样写啊

#4


如果你的序列 不是要求必须连续那可以这样。

select max_seq into x_maxseq from tb_tradenum for update nowait
update tb_tradenum set max_seq = max_seq + 1;
commit;

#5


LOCK TABLES tbl_name [AS alias] {READ | [LOW_PRIORITY] WRITE}
            [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。 

如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READ或WRITE表,其他线程被阻止。 

每个线程等待(没有超时)直到它获得它请求的所有锁。 

#6


唠叨大哥,能具体一点吗?

#1


1。创建序列
  create sequence SEQNAME
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;
2。使用序列
20040909+0001------〉'20040909'||SEQNAME.NEXTVAL

#2


我看不懂你的代码。
我一般这样处理  select * from tb_tradenum for update nowait
将纪录锁上。

#3


我的过程是
查询表获取数据,然后对数据分析;从而进行update表,或删除旧的,添加新的

如果将纪录锁上了,那怎么样把他解开呢,在没解锁前其他用户一直等待吗?
commit?在代码里怎样写啊

#4


如果你的序列 不是要求必须连续那可以这样。

select max_seq into x_maxseq from tb_tradenum for update nowait
update tb_tradenum set max_seq = max_seq + 1;
commit;

#5


LOCK TABLES tbl_name [AS alias] {READ | [LOW_PRIORITY] WRITE}
            [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。 

如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READ或WRITE表,其他线程被阻止。 

每个线程等待(没有超时)直到它获得它请求的所有锁。 

#6


唠叨大哥,能具体一点吗?