mysql数据库insert插入重复问题

要求:ID不能递增。点击保存按钮从数据库中取出目前最大数据加1。如目前是A1033下一个是A1034。怎么保证多处同时点击保存ID不重复。。不能使用锁表。界面端需要返回这... 要求:
ID不能递增。
点击保存按钮从数据库中取出目前最大数据 加1。如目前是A1033 下一个是A1034。
怎么保证多处同时点击保存ID不重复。。
不能使用锁表。
界面端需要返回这个ID。
需要在界面端知道这个ID. 保证不能主键冲突。
不能用触发器
----------------------------
这是排队机程序。
多种业务分A,B,C,D,每天计数从A001,B001,开始,现在是锁表解决唯一性,先锁表接着查出最大值再加1然后再解锁,但是锁表后并发高了会报错。
有多个取票端,所以在程序中递增是不可能的。
因为要接着打印出票号,需要在插入数据库前就得有这个票号,所以不能用id递增。
有多种票号类型都是不同的,数据都在一个表里,再次否决id递增。
展开
 我来答
yyq2012aa
2013-11-19 · 超过56用户采纳过TA的回答
知道小有建树答主
回答量:107
采纳率:0%
帮助的人:131万
展开全部
这就是自己实现一个ID自增的东西。
比如的你有个公用类专门用来生成后面的数字,所有需要用到的方法都调用这个类的一个方法我们就叫它nextId吧,只要这个方法是线程安全的就可以了。
IdUtils.nextId()

int nextId() {
lock(this){
return this.id++;

}
}
应用启动的时候从数据库查询一下id的最大值并设置给工具类的id,让它接着增长就行了。
具体实现看你用什么语言。

请仔细阅读别人回答的是什么意思。想想oracle的sequence的实现,是不是类似?
追问
1、应用启动的时候从数据库查询一下id的最大值并设置给工具类的id,让它接着增长就行了。
这个方法单一客户端是完全解决,但是客户端是多个的。
2、用的是mysql 他没有sequence,就算有,里面的字段都是灵活配置的,每个类型都必须每天从一开始计数根据英文字母A,B,C,D进行类别区分。
A001 ,A002
B001,B002
C001 这种类型。
追答
  1. 客户端多个的话你是让客户端带着这个(A001或者B001)标示来统一个数据库存储吗?

  2. 如果是多种类型,那相当于你有多个工具类(这时候应该叫ID生成类)的是实例,设置初始值的时候去数据库里面查找对应类的最大值并设置。

  3. 不知道我理解有没有问题。

左岸吸血鬼
2013-11-20
知道答主
回答量:7
采纳率:0%
帮助的人:1万
展开全部
--自增ID 格式:yyyyMMdd***
--===================================================
--存储过程
CREATE PROCEDURE get_new_id
@NEW_ID VARCHAR(16) OUTPUT
AS
BEGIN
DECLARE @DATE DATETIME
DECLARE @YYYY VARCHAR(4)
DECLARE @MM VARCHAR(2)
DECLARE @DD VARCHAR(2)
--保存取得的当前时间
SET @DATE = GETDATE()
SET @YYYY = DATEPART(yyyy, @DATE)
SET @MM = DATEPART(mm, @DATE)
SET @DD = DATEPART(dd, @DATE)
--位数不够的前面补0
SET @YYYY = REPLICATE('0', 4 - LEN(@YYYY)) + @YYYY
SET @MM = REPLICATE('0', 2 - LEN(@MM)) + @MM
SET @DD = REPLICATE('0', 2 - LEN(@DD)) + @DD
--取出表中当前日期的已有的最大ID
SET @NEW_ID = NULL
SELECT TOP 1 @NEW_ID = [字段名] FROM [表名] WHERE [字段名] LIKE @YYYY+@MM+@DD+'%' ORDER BY [字段名] DESC
--如果未取出来
IF @NEW_ID IS NULL
--说明还没有当前日期的编号,则直接从1开始编号
SET @NEW_ID = (@YYYY+@MM+@DD+'001')
--如果取出来了
ELSE
BEGIN
DECLARE @NUM VARCHAR(3)
--取出最大的编号加上1
SET @NUM = CONVERT(VARCHAR, (CONVERT(INT, RIGHT(@NEW_ID, 3)) + 1))
--因为经过类型转换,丢失了高位的0,需要补上
SET @NUM = REPLICATE('0', 3 - LEN(@NUM)) + @NUM
--最后返回日期加编号
SET @NEW_ID = @YYYY+@MM+@DD + @NUM
END
END
GO
===================================================
--触发器
CREATE trigger [dbo].[触发器名] on [dbo].[表名]
instead of insert
AS
SET NOCOUNT ON ;
begin
declare @id varchar(16)
select * into # from inserted
EXECUTE get_new_id @id OUTPUT
update # set 字段名 = @id
insert 表名 select * from #
end
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
millerrch
2013-11-19 · TA获得超过357个赞
知道小有建树答主
回答量:234
采纳率:0%
帮助的人:214万
展开全部
用触发器来实现每次新增数据都加1,每次添加时用触发器来生成id值
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
twvampire
2013-11-19 · TA获得超过3620个赞
知道大有可为答主
回答量:3029
采纳率:76%
帮助的人:2996万
展开全部
没具体明白你什么意思,
如果只是不想叫他重复,直接加个主键不就可以了,,,,
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式