存储过程 线程安全问题 如题线程安全问题 在存储过程里面如何实现 从一个表取数据,保证在存储过程这一级 就 实现 望高手赐教 目前知道用序列 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全 其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理 看来论坛高手都藏起来了额 其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理 看来论坛高手都藏起来了额就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101 第三个就是102 等等 ,需要在 数据库用存储过程实现 怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作 其实很简单,你看看当前的序列的值,序列名.curval 和数据块里最大的值是否一样,一样说明序列没有被使用,线程安全没有那么简单,这个值 他有一个前缀,并且是变化的 , 后面几位是递增的如果使用序列,那得很多序列 如果用一个的话 有点棘手 我正在试着处理 看来论坛高手都藏起来了额就是我想从 数据库一个表中 取 一个最大值 ,然后多个用户同时 会取 ,我想 第一个用户得到 100 假如,第二个就是101 第三个就是102 等等 ,需要在 数据库用存储过程实现 怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作不是这个意思了 是多用户同时访问,这种等待的 肯定不行, 必须处理一下。我的目的并不是插入,而是 取得 保证取得的 时候 都是唯一但是取前肯定插入了 ,目前存在现成问题是在解决这个现成问题 序列就可以啊,你插入的时候获取插入的序列sql语句 insert 表名(id,其他列) values(序列.nextval ,其他列值) returning id into 存储过程变量 可以采用比较笨的方法,在操作表前先锁住 比如FORUPDATE,取出当前值,+1后在commit另外,如果是JAVA的话,可以在该方法前加上关键字synchronized。 提供一个,仅供参考!/** * 取最后四位数,同时更新,出现断号正常 * @return * @throws Exception */ public synchronized String getLastNumber()throws Exception{ Connection conn = null; String num =""; try{ conn = this.getConnection(); conn.setAutoCommit(false); num = numberDao.getLastNumber(conn); numberDao.updateLastNumber(conn, num); conn.commit(); }catch(Exception e){ conn.rollback(); e.printStackTrace(); throw new Exception(e.getMessage()); }finally{ if(conn!=null){ conn.close(); } } return num; } 使用seq 真能保证挨个有序么?SELECT SEQ.NEXTVAL,SEQ.CURRENTVAL FROM DUAL;看看结果呢 lz思路有点乱,如果只是查询时就给最大值加1,可以试试包变量的方式,以下是我写的简单例子。如果查询出来没有用时还还把号还回去,就需要写比较复杂的逻辑了,可以通过包变量或在java等程序代码中实现判断后,在向数据库写入时控制去重复。SQL> SQL> create table test(a number); Table createdSQL> insert into test values (101); 1 row insertedSQL> insert into test values (102); 1 row insertedSQL> insert into test values (103); 1 row insertedSQL> 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 createdSQL> 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 现在我用 锁表的方式 实现了 。 不过又有一个新问题 , 我把 数据库名 当参数 传递进来 ,然后 用 立即执行 ,然后总出异常ls_tmp_sql := 'select nvl(max(to_number(substr('||ls_fsjkzdm||','||ls_sub_num||'))),1) from '||ls_fsjkmc||'.'||ls_fsjkbm||' where '||ls_fsjkzdm||' like '||'''%'||ls_tmp_pre||'______%'||''';'; --execute immediate ls_tmp_sql into lh_tmp1;求高人看看 我这个 写的 对不对此外 into写到 select 值的 后面也是不对 总 异常 like '||'''%'||ls_tmp_pre||'______%'||''';';--此处在语句内部不需要“;”号了,改为like '||'''%'||ls_tmp_pre||'______%'||''''; 2个select放进另一个select中能否实现 请大家解决存储过程的问题 谢谢了!!! 关于diptester工具自动同步的问题. 帮忙看条SQL语句 PL/SQL 关于中变化表和限制表 SOS!大家帮忙 oracle的如何从服务器上导数据库 一个关于日期函数的简单问题 请问一个SQL语句的写法 给高分!在线紧急求救! 大神们帮忙看一下 告警日志 800万条数据去除重复数据有没有好的建议?
怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作
怎么会复杂啊,难道需求没有说清楚?还是表达没有说清楚?你每次取序列都是值:序列名.nextval吧 例如取到的值为102而表中已经插入的最大值为100 ,那么说明还有101没有进行数据插入,你的应用进程必须等到101插入之后,再进行操作不是这个意思了 是多用户同时访问,这种等待的 肯定不行, 必须处理一下。我的目的并不是插入,而是 取得 保证取得的 时候 都是唯一但是取前肯定插入了 ,目前存在现成问题是在解决这个现成问题
另外,如果是JAVA的话,可以在该方法前加上关键字synchronized。
/**
* 取最后四位数,同时更新,出现断号正常
* @return
* @throws Exception
*/
public synchronized String getLastNumber()throws Exception{
Connection conn = null;
String num ="";
try{
conn = this.getConnection();
conn.setAutoCommit(false);
num = numberDao.getLastNumber(conn);
numberDao.updateLastNumber(conn, num);
conn.commit();
}catch(Exception e){
conn.rollback();
e.printStackTrace();
throw new Exception(e.getMessage());
}finally{
if(conn!=null){
conn.close();
}
}
return num;
}
SELECT SEQ.NEXTVAL,SEQ.CURRENTVAL FROM DUAL;看看结果呢
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>
--execute immediate ls_tmp_sql into lh_tmp1;求高人看看 我这个 写的 对不对此外 into写到 select 值的 后面也是不对 总 异常
like '||'''%'||ls_tmp_pre||'______%'||'''';