恳请大家帮我分析一下,谢谢。

marcovanbasten 2005-10-21 10:19:07
我现在有多个线程,同时访问一个数据表。每个线程的任务都是一样的,就是每次取一条记录进行分析,然后将这条记录删掉。为了防止多个线程同时访问同一条记录,我的SQL是这么写的:
select x, xx, xxx from t where ROWNUM = 1 for FOR UPDATE NOWAIT。
我的问题是,如果当一个线程访问一条正在被其他线程处理的记录时,应该是报错的,如何才能让线程自动知道哪条记录没有被锁定?从而可以提高效率。
环境是weblogic + oracle
...全文
129 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
有N个处理器负责数据,但这些处理器取数据的条件又有可能是不一样的,比如说处理器A可能只选择代码等于A的,处理器B只选择代码等于B的,为了使它们尽量做到负载均衡并且不出问题,只好一个处理器起一个线程,去访问数据库了。
你觉得如何设计才好呢?
sasacat 2005-10-21
  • 打赏
  • 举报
回复
数据库不大你还搞这么多线程做什么?....
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
我也觉得效率不高,就是因为需要频繁访问数据,主要是我想让每个线程比较均衡的执行任务,而且表里的数据总的数量不是很大,所以我想就是一次就只取一条了。唉……
sasacat 2005-10-21
  • 打赏
  • 举报
回复
自动知道哪条数据没有被锁定?这个很难啊。Oracle只有在访问到那条数据的时候才知道那条数据有没有被锁定,因为这个锁是加在块上的。

你不如一次取一百条来分析....:) 应该会快一点吧
qiaozhiwei 2005-10-21
  • 打赏
  • 举报
回复
还要注意线程的同步
qiaozhiwei 2005-10-21
  • 打赏
  • 举报
回复
提供方案,仅供参考:
我认为你这样效率不高,而且要频频读取数据库,这样,你可以起一个线程专门读写数据库,读到一个记录集然后把每个记录放到不同的变量里(可以是个数组),每个线程访问自己的数据就可以了
sasacat 2005-10-21
  • 打赏
  • 举报
回复
这个可以不用担心。可以用事务来处理嘛。在数据库里再建立一个表嘛,取完了数据,然后在另一个表中记下取到第几条了。再提交...
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
我觉得第一位兄弟提的想法也很好,有一个线程专门负责从数据库中取数据,存在一个内存块儿中,然后各个处理器可以从这个内存块儿中取各自需要的数据。
这样即能降低访问数据库的频率,也可以使处理器的负载比较均衡,不知道大家还有什么好办法没有呢。
tiantiancn 2005-10-21
  • 打赏
  • 举报
回复
初学者.看两位的讨论真是长进不少.到最后,觉得问题确实还没有解决.是啊,"有可能一个处理器还没来得及记上取到第N条了,其他的处理就取走了。"
sasacat 2005-10-21
  • 打赏
  • 举报
回复
是啊,如果是这样就不用锁定了.... 那也不会报错了。真是一举两得呀.....|||

虽然如此,我还是觉得你测试一下效率,看一个处理全部最后再一次性提交快,还是分开处理快
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
你取完了就在程序里记上(已经取到第N条了),下面一个处理器就从N+1开始取?
-----------------------------

其实这种作法也很容易导致多个处理器同时访问一段数据。有可能一个处理器还没来得记上取到第N条了,其他的处理就取走了。
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
你取完了就在程序里记上(已经取到第N条了),下面一个处理器就从N+1开始取?
-----------------------------

如果要是这样的话,我想就没必要用for FOR UPDATE NOWAIT了吧?
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
嗯,我原来就是这样想的,我甚至想把那个100设置成可配置的,让用户自己去配去。数据量大的就多配点,数据量小的少配点。
如果其他处理器访问到已经被锁定的这一百条,是不是会报错?
又回到我最开始的问题去了。如果其他处理器的线程访问一次已经被锁定的记录,报错,再来,又访问到了这些锁定的记录,感觉不太好。
所以我就想知道如何设计才能其他线程可以把那些已经被锁定的记录剔除出去?只访问那些可以被访问的记录。
sasacat 2005-10-21
  • 打赏
  • 举报
回复
你取完了就在程序里记上(已经取到第N条了),下面一个处理器就从N+1开始取?
sasacat 2005-10-21
  • 打赏
  • 举报
回复
就用你说的select x, xx, xxx from t where ROWNUM <= 100 for FOR UPDATE NOWAIT啊,你的其它处理器就知道了嘛....
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
如果某个处理器一次性取走了100条记录,那如何设计才能保证其他处理器不再访问这100条记录呢?
sasacat 2005-10-21
  • 打赏
  • 举报
回复
你的处理器这么不经用啊?闲一下又不会生锈,你的数据量也不大。如果一个批处理比N个一条一条快,为什么不能只用一个呢? 你硬要分开,就这个处理器取代码A的前100条,那个取代码A的101--200条....反正一个一个的处理是非常非常不合数据库的开发原则的。
marcovanbasten 2005-10-21
  • 打赏
  • 举报
回复
但是可能有n个处理代码A的处理器,有n个处理代码B的处理器,如果一个全取完,其他的处理器就会闲置的。所以我想到了一条一条取。这样的负载肯定是最均衡的,但却是以频繁访问数据库作为代价的。
sasacat 2005-10-21
  • 打赏
  • 举报
回复
我意思是你别一次取一条啊....你就这个处理器一下子把代码等于A的全取过来,然后一条一条改完之后再来个commit....那个处理器一下子把代码等于B的全取过来,然后一条一条改完之后再来个commit....我不知道你具体的“处理”是什么哈,想象中是这样比较快

3,490

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧