日期:2014-05-16  浏览次数:20890 次

存储过程 线程安全问题
如题

线程安全问题 

在存储过程里面如何实现 

从一个表取数据,保证在存储过程这一级 就 实现 

望高手赐教 

目前知道用序列 

------解决方案--------------------
在表中读取完某个字段最大值,然后这个字段最大值在下次读取时自动+1?

建议楼主还是具体讲讲你实际的应用,想要达到的效果,最好有示例说明。现在比较难以理解这样做的意义在哪里。
------解决方案--------------------
引用:
就是说 我想在办业务的时候得到一个值,这个值不能重复

而这个值是个 递增的 值 ,目前的 实现是 从一个表中取得最大的 ,下次用的时候+1

这样的实现多线程的时候,就会出现问题 ,会有重复的 


哦,理解你的意思了,你就是想办业务的时候,给每个业务生成一个唯一标识,目前这个标识是从一个表中取最大值,下次用的时候把最大值+1作为唯一标识。同时更新这个表。你现在要把这个过程封装成一个存储过程。
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101  第三个就是102 等等 ,需要在 数据库用存储过程实现 。



其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全


没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的

如果使用序列,那得很多序列 如果用一个的话 有点棘手 

我正在试着处理  看来论坛高手都藏起来了额


就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101  第三个就是102 等等 ,需要在 数据库用存储过程实现 
怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?

你每次取序列都是值:序列名.nextval吧 例如取到的值为102

而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作
------解决方案--------------------
序列就可以啊,你插入的时候获取插入的序列

sql语句 

insert  表名(id,其他列)  values(序列.nextval ,其他列值) returning id into 存储过程变量
------解决方案--------------------
可以采用比较笨的方法,在操作表前先锁住 比如FORUPDATE,取出当前值,+1后在commit
另外,如果是JAVA的话,可以在该方法前加上关键字synchronized。

------解决方案--------------------
使用序列,OR存储过程中手工加锁。。。
------解决方案--------------------
lz思路有点乱,如果只是查询时就给最大值加1,可以试试包变量的方式,以下是我写的简单例子。如果查询出来没有用时还还把号还回去,就需要写比较复杂的逻辑了,可以通过包变量或在java等程序代码中实现判断后,在向数据库写入时控制去重复。
SQL> 
SQL> create table test(a number);
 
Table created
SQL> insert into test values (101);
 
1 row inserted
SQL> insert into test values (102);
 
1 row inserted
SQL> insert into test values (103);
 
1 row inserted
SQL> insert into test values (104);
 
1 row inserted
 
SQL> commit;
 
Commit complete
 
SQL> 
SQL> create or replace package testp is
  2    seqNo number := 0;
  3    strNoHead varchar2(8000) := '';