不好意思,光标定义写错了
应当是
cursor c_mq is
select mqid from t_mqid
where status ='I' order by mqid;
以上是临时写的,只要大家理解意思就可以。
还需要补充说明的是,任务必须一条一条的执行(不要问为什么,必须要这样),
有很多进程(终端)同时执行任务,一个任务又不能被执行2遍。
应当是
cursor c_mq is
select mqid from t_mqid
where status ='I' order by mqid;
以上是临时写的,只要大家理解意思就可以。
还需要补充说明的是,任务必须一条一条的执行(不要问为什么,必须要这样),
有很多进程(终端)同时执行任务,一个任务又不能被执行2遍。
cursor c_mq is
select mqid from t_mqid
where status ='I' order by mqid
for update;
他的做法是保证update时没有别的session修改该表,否则,返回异常。保证修改与选择的scn的一致性。
你的做法是锁定该记录,不让别人以for update打开。但你想过没有,第二个session for update试图打开第一个session 打开的记录时,他会等待的,但第一个session提交后,他的for update打开又会成功,update也会成功,则一个记录被处理了两遍。
--------------------
如果说他的方案还可行的话,你的方案不可行。
提交后status为'U',第二个session不再读取。
使用for update,至少保证了在打开游标到更新结束的过程中,没有其他的进程能对这个表进行更新。这就符合了题意。
两种做法确实有所区别,正如你讲的,但是采用第一种做法时如果用户再次请求修改操作,那结果不是和第二种做法一模一样吗?
其实这更多的是业务逻辑的问题。
我想想,也行的通。
比我的办法好,
我的办法有一个局限,就是第一个session在select and update之间,表不能有更新,否则,就会异常。
你的办法可以处理到session1 and session2处理不同记录时,就不会发生冲突了。
我看看大家还有好的建议没有,谢谢大家
在
set transaction isolation level serializable;
中,session 必须保证更新的时候的记录集和select时的一样,否则就会异常。
当再次去取的时候,前一session已把标志位修改了,取不到了,所以是不可能重复执行的。
你再想想是不是这样。
to bachelor(鹰飞九月)
其实njc_ly(路言)的方法在你的过程中,作用是一样的。
因为所有的session都是select mqid into v_mqid from t_mqid
where status ='I' order by mqid for update nowait;
的话,因为对所有的I标志加锁,别的session都会异常。
除非你改写过程并优化,否则还是用你原来的好。
在
set transaction isolation level serializable;
中,session 必须保证更新的时候的记录集和select时的一样,否则就会异常。
当再次去取的时候,前一session已把标志位修改了,取不到了,所以是不可能重复执行的。
你再想想是不是这样。
to bachelor(鹰飞九月)
其实njc_ly(路言)的方法在你的过程中,作用是一样的。
因为所有的session都是select mqid into v_mqid from t_mqid
where status ='I' order by mqid for update nowait;
的话,因为对所有的I标志加锁,别的session都会异常。
除非你改写过程并优化,否则还是用你原来的好。
定义cursor时不用for update,在fetch一行后再对这一行做一个select .. into .. from ... where ... for update nowait,如果成功则对这一行处理,否则fetch下一行。
这样设计各session可以并行处理。