首页 新闻 会员 周边 捐助

同时操作数据库引起的违反唯一性问题

0
悬赏园豆:20 [已解决问题] 解决于 2012-03-04 22:56

假设我有一个表 table,里面有个字段 num 是 int 型,从1一直到 N,递增的,不可重复。现在有一个 new.jsp 页面,功能是显示该表的内容,并且接受用户提交表单往这个表插数据,form 的 action 是 insert.jsp,改页面的功能是接受 new.jsp 的表单内容,并且从表 table 里面查出最大的 num,假如是 m,然后加 1,并将(m+1)连同从 new.jsp 表单里面获得的信息一起插入到数据库。这是个简单我业务逻辑,(不知道我说清楚了没有),现在有一个问题,亮个用户 u1 和 u2,同时提交表单 form,这时两个人都得到一个最大的 num,设为 n,u1 经过处理后将(n+1)插入到数据库,而u2 也将处理后的(n+1)准备插入到数据库,这时就报错了。这只是两个用户同时提交,而实际中可能有多个用户同时提交,怎么从根本上解决这个问题。不好意思,我是新人,求理解,求指点,多谢各位大虾!!!

载心问情的主页 载心问情 | 初学一级 | 园豆:155
提问于:2012-02-27 22:08
< >
分享
最佳答案
0

1 可以使用递增的GUID,不要每次加1。

2 你的其实是可以实现的,思路参考数据库更新锁

收获园豆:20
碧落星痕 | 小虾三级 |园豆:708 | 2012-02-28 11:59

是不是当一个用户访问这个表时,给他加上一个锁,别的用户就不能访问这个表,直到第一个用户解锁。好晦涩啊,能不能解释的更清楚些?

载心问情 | 园豆:155 (初学一级) | 2012-02-28 18:55

@心中的詩: 按照数据库实现机制一样,做共享锁,排他锁,更新锁,数据被查询时,给一个共享锁,当有用户准备更新时,把共享锁改成更新锁,开始更新时,把更新锁改成排他锁.

要点:用户可以查询有共享锁或更新锁得数据,可以准备更新有共享锁的数据,并给数据加更新锁;如果一个数据已经有别的用户的更新锁,那其他用户无法给数据加更新锁.如果当前用户已准备好更新数据,那么将更新锁改为排它锁并开始更新.排他锁为最高级的锁,如果数据被排它锁锁定,那么其他用户不能查询,当然更不能更新.

以上为数据库的实现机制,自己来做很麻烦,效率也低.

 

碧落星痕 | 园豆:708 (小虾三级) | 2012-02-28 21:03
其他回答(4)
0

既然是自增的,就让数据库的这个字符自增不就行了,为什么还要程序中生成呢?

LCM | 园豆:6876 (大侠五级) | 2012-02-27 22:13

这是系统中的一个模块的业务流程,我只是为了好说明简化了

支持(0) 反对(0) 载心问情 | 园豆:155 (初学一级) | 2012-02-27 23:15
0

设置为自增后,可以不管这个字段。

或者在插入前获取最大的值再加一

小小刀 | 园豆:1991 (小虾三级) | 2012-02-27 22:30
1

用了自动增加序列就不能插入了,只能靠系统自己加。你先确定下这个id是不是页面所需要的。即是否参与流程。如果一定要建议你用sequence  或者sequence 的思路,放弃使用自动增加序列

死白的man | 园豆:2135 (老鸟四级) | 2012-02-27 23:01

其实系统中的这个ID是经过一个类处理过的,比如有个这样的 RN-120201,RN是文件类型,12是2012年,02是2月,就是这样的一个号码,依次增加,(不完全要求绝对以 1 递增),但是不可以重复。

这个问题可不可以从页面入手,比如把那段数据库操作代码处理下,同一段时间只能一个用户访问或操作之类的。

支持(0) 反对(0) 载心问情 | 园豆:155 (初学一级) | 2012-02-27 23:20

@心中的詩: 如果你使用sequence  则肯定不会存在你说的问题,不管多大的并发

支持(0) 反对(0) 死白的man | 园豆:2135 (老鸟四级) | 2012-02-28 08:16
0

使用数据事务,就能保证原子性了。

祭天 | 园豆:202 (菜鸟二级) | 2012-03-03 16:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册