多线程并发处理
数据库里有两个表A,表B,结构一样。
需要做的是把表A的数据拿出来,处理后放到表B。
现在我是用线程取,每10秒调用一次存储过程。
每次取100条数据。
存储过程如下:
UPDATE t_tableA SET PushStatus =0 WHERE PushStatus=-1 limit 100
SELECT ID,Name,Content FROM t_tableA WHERE PushStatus = 0;
INSERT INTO t_tableB SELECT * FROM t_tableA WHERE PushStatus = 0;
DELETE FROM t_tableA WHERE PushStatus=0;
package cn;
public class Thread implements Runnable{
private String sendUrl ;
private int milliSecond ;
public SmsSendThread(String sendUrl, String milliSecond) {
this.sendUrl=sendUrl;
this.milliSecond=Integer.parseInt(milliSecond);
}
public void run() {
while(true){
try {
Thread.sleep(milliSecond);
Service.getInstance().send(sendUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Thread sst = new Thread(sendUrl,milliSecond);
new Thread(sst).start();
new Thread(sst).start();
new Thread(sst).start();
UPDATE t_tableA SET PushStatus =0 WHERE PushStatus=-1 limit 100
SELECT ID,Name,Content FROM t_tableA WHERE PushStatus = 0;
INSERT INTO t_tableB SELECT * FROM t_tableA WHERE PushStatus = 0;
DELETE FROM t_tableA WHERE PushStatus=0;
方案3-分角色线程:
这个场景中,有四个操作:读取数据、处理数据、转移数据、清理数据。
所以我们可以分成三种不同的线程来处理:
1、读取线程Read:负责读取数据,update和select操作,先update成处理中状态PushStatus=0,select获取数据,然后分配给数据处理线程Deal来做。
2、数据处理线程Deal:负责处理数据,处理完毕后update成完成状态PushStatus=2,因为数据都是读取线程Read传过来的,由读取线程统一管理,所以数据处理线程只管处理,不用考虑数据的冲突,真正实现并发操作。
3、清理线程Clear:负责把已完成PushStatus=2的数据转移到B表,然后清理A表。【清理的时候也涉及到数据冲突的问题,类似上面的情况,就不再讨论了】
点评:这三种线程角色相互独立,可以并行;而同一种线程角色中又可以并发,实现横向和纵向的并发。
但是结构相对比较复杂,适合规模大的负责的业务场景。
理想状态:
读取线程Read获取数据后调用数据处理线程Deal,在Deal处理过程中,Read继续获取新的数据,等Deal处理完毕了,Read刚好获取完新的数据,然后又传到Deal中来处理。【两者线程数量的比例根据各自处理时间来定】
另外,如果B表的实时性不高的话,清理线程Clear一个就够了,让他每隔一段时间扫一扫就可以了。
楼主也可以结合不同方案,组合成一个新的构想!
[解决办法]
你可以先把记录分页,然后一个线程去处理一页的数据。