读书人

存储过程 线程安全有关问题

发布时间: 2013-07-01 12:33:04 作者: rapoo

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

线程安全问题

在存储过程里面如何实现

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

望高手赐教

目前知道用序列
[解决办法]
在表中读取完某个字段最大值,然后这个字段最大值在下次读取时自动+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) := '';


4 function getNext(sourceNo number) return varchar2;
5 end testp;
6 /

Package created
SQL> create or replace package body testp is
2 function getNext(sourceNo number) return varchar2 is
3 strRet varchar2(8000);
4 begin
5 strNoHead := 'xxx';
6 if (sourceNo >= seqNo) then
7 seqNo := sourceNo;
8 end if;
9 seqNo := seqNo + 1;
10 strRet := strNoHead
[解决办法]
to_char(seqNo);
11 return strRet;
12 end;
13 end testp;
14 /

Package body created

SQL> select testp.getNext(max(a)) from test;

TESTP.GETNEXT(MAX(A))
--------------------------------------------
xxx105

SQL> select testp.getNext(max(a)) from test;

TESTP.GETNEXT(MAX(A))
--------------------------------------------
xxx106

SQL> select testp.getNext(max(a)) from test;

TESTP.GETNEXT(MAX(A))
--------------------------------------------
xxx107

SQL>
[解决办法]
抱歉,这个不行,忘记测试了,不能突破session
[解决办法]
还是建议用锁、物理表、序列或在代码端用共同调用中的全局变量来控制。
[解决办法]
like '
[解决办法]
'''%'
[解决办法]
ls_tmp_pre
[解决办法]
'______%'
[解决办法]
''';';--此处在语句内部不需要“;”号了,改为
like '
[解决办法]
'''%'
[解决办法]
ls_tmp_pre
[解决办法]
'______%'
[解决办法]
'''';

读书人网 >oracle

热点推荐