假设我有一个表 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)准备插入到数据库,这时就报错了。这只是两个用户同时提交,而实际中可能有多个用户同时提交,怎么从根本上解决这个问题。不好意思,我是新人,求理解,求指点,多谢各位大虾!!!
1 可以使用递增的GUID,不要每次加1。
2 你的其实是可以实现的,思路参考数据库更新锁
是不是当一个用户访问这个表时,给他加上一个锁,别的用户就不能访问这个表,直到第一个用户解锁。好晦涩啊,能不能解释的更清楚些?
@心中的詩: 按照数据库实现机制一样,做共享锁,排他锁,更新锁,数据被查询时,给一个共享锁,当有用户准备更新时,把共享锁改成更新锁,开始更新时,把更新锁改成排他锁.
要点:用户可以查询有共享锁或更新锁得数据,可以准备更新有共享锁的数据,并给数据加更新锁;如果一个数据已经有别的用户的更新锁,那其他用户无法给数据加更新锁.如果当前用户已准备好更新数据,那么将更新锁改为排它锁并开始更新.排他锁为最高级的锁,如果数据被排它锁锁定,那么其他用户不能查询,当然更不能更新.
以上为数据库的实现机制,自己来做很麻烦,效率也低.
既然是自增的,就让数据库的这个字符自增不就行了,为什么还要程序中生成呢?
这是系统中的一个模块的业务流程,我只是为了好说明简化了
设置为自增后,可以不管这个字段。
或者在插入前获取最大的值再加一
用了自动增加序列就不能插入了,只能靠系统自己加。你先确定下这个id是不是页面所需要的。即是否参与流程。如果一定要建议你用sequence 或者sequence 的思路,放弃使用自动增加序列
其实系统中的这个ID是经过一个类处理过的,比如有个这样的 RN-120201,RN是文件类型,12是2012年,02是2月,就是这样的一个号码,依次增加,(不完全要求绝对以 1 递增),但是不可以重复。
这个问题可不可以从页面入手,比如把那段数据库操作代码处理下,同一段时间只能一个用户访问或操作之类的。
@心中的詩: 如果你使用sequence 则肯定不会存在你说的问题,不管多大的并发
使用数据事务,就能保证原子性了。