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);
}
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;
方案1-模仿CAS的无阻塞算法: 【缩小更新的粒度】
1、先找出符合要求的100条;
SELECT ID,Name,Content FROM t_tableA WHERE PushStatus=-1 limit 100
2、处理每条数据,处理前先更新,更新成功后再处理。(这样能避免数据的重复处理,把同步的任务交给了数据库)
UPDATE t_tableA SET PushStatus=0 WHERE PushStatus=-1 AND ID=:ID
3、对该条数据进行insert和delete,此处的修改都是按照ID的,所以不会造成冲突。
点评:没有使用锁,线程间不用阻塞等待。但是每条数据都要分开更新,如果每条数据处理时间很短的话,那么效率就会大打折扣。
方案2-读取锁:
1、更新-读取-更新:先更新是为了批量获取,获取后再更新是为了批量占用已选数据。
把这个过程锁起来,保证每次读的时候不会冲突,这样就不会产生重复处理的数据了。
UPDATE t_tableA SET PushStatus=0 WHERE PushStatus=-1 limit 100;
SELECT ID,Name,Content FROM t_tableA WHERE PushStatus = 0;
UPDATE t_tableA SET PushStatus=2 WHERE PushStatus=0;
点评:在读取的时候加锁,读取和占用更新都是批量的,既解决了数据冲突的问题,也大大减少数据库的操作次数。
但是,由于加了读取锁,所以要尽量增大每次读取的数量,减少读取的次数,否则锁竞争会影响效率。