67,513
社区成员
发帖
与我相关
我的任务
分享
public synchronized List findPushList(HashMap searchMap) {
// TODO Auto-generated method stub
this.status = transactionManager.getTransaction(definition);
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//获取全部的未发送信息
List list = this.queryForList("findPushList",
searchMap);
try {
//修改信息状态
for(int n=0;n<list.size();n++){
HashMap listMap = (HashMap)list.get(n);
searchMap.put("smsId", listMap.get("SMS_ID"));
this.update("updatePushListById",searchMap);
}
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw new RuntimeException(e);
}
return list;
}
public synchronized void insertPushLog(HashMap searchMap) {
// TODO Auto-generated method stub
this.status = transactionManager.getTransaction(definition);
definition
.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
try {
this.insert("insertPushLog", searchMap);//添加数据操作记录
this.delete("deletePushList", searchMap);//删除原表记录
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw new RuntimeException(e);
}
}
public class Pusher implements Runnable {
private Message message = new Message();
private HashMap<String, Object> searchMap = new HashMap<String, Object>();
private volatile boolean stop = false;
private MessageMgrFacadeImpl messageMgrFacadeImpl = null;
@Override
public void run() {
// 注入DAO
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
messageMgrFacadeImpl = (MessageMgrFacadeImpl) context
.getBean("messageMgrFacade");
searchMap.put("pushTime", DateUtil.getCurrentTimeFull());
searchMap.put("maxCount", Config.getInstance().getMaxCount());
// 获取未发送信息记录
List list = messageMgrFacadeImpl.findPushList(searchMap);
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
HashMap listMap = (HashMap) list.get(i);
System.out.println("++++==" + i + ":" + listMap);
//.....接口操作 HashMap<String, Object> search = new HashMap<String, Object>();
search.put("smsId", smsId);
search.put("errorCode", returnResult);
search.put("errorMsg", ReturnMessage.getInstance()
.getMsgByCode(returnResult));
// 保存返回信息
messageMgrFacadeImpl.insertPushLog(search);
}
} else {
// 休息1s
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log4jInitialize.logger(ManagerThread.class).error(
"Pusher.run方法异常:" + e);
e.printStackTrace();
}
}
}
}
SELECT T.SMS_ID,
T.USER_ID,
T.SMS_TYPE,
T.SCH_ID,
T.SMS_TITLE,
T.SMS_CONTENT,
TO_CHAR(T.SMS_CREATE_DATE,'YYYY-MM-DD HH24:MI:SS') CREATE_DATE,
TO_CHAR(T.SMS_PUSH_DATE,'YYYY-MM-DD HH24:MI:SS') PUSH_DATE,
T.SCH_LEVEL FROM SMS_PUSH T
WHERE T.SMS_ID IN(
SELECT * FROM(SELECT A.SMS_ID
FROM SMS_PUSH A
WHERE 1=1
AND A.SMS_PUSH_STATE IS NULL
<isNotEmpty property="userType">
AND A.SMS_TYPE = #userType#
</isNotEmpty>
<isNotEmpty property="pushTime">
AND TO_CHAR(A.SMS_PUSH_DATE,'YYYY-MM-DD HH24:MI:SS') < #pushTime#
</isNotEmpty>
ORDER BY A.SMS_ID)WHERE ROWNUM <= $maxCount$
) FOR UPDATE NOWAIT SKIP LOCKED
[/quote]
不要在数据库层加锁,因为这样可能会导致很多不必要的麻烦。可以按照下面的建议试一下:
1.同步的代码有问题,因为你的messageMgrFacadeImpl都不是单例的,代码中的同步没有实际意义,将messageMgrFacadeImpl写成单例模式,或者将messageMgrFacadeImpl中的方法都设置为static的。
2.SQL语句我看了一下应该是不会出现重复数据的,可能是数据库中的数据本身就有问题,执行一下selet t1.SMS_ID from table1 t1, table2 t2 where t1.SMS_ID = t2.SMS_ID;
如果查询有结果数据返回,说明是数据库中的数据本身就有问题,自己根据情况把重复的数据清理掉。还要思考一下为什么会出现数据问题,是之前的操作失误,还是SMS_ID的生成方式确实有问题。
SELECT T.SMS_ID,
T.USER_ID,
T.SMS_TYPE,
T.SCH_ID,
T.SMS_TITLE,
T.SMS_CONTENT,
TO_CHAR(T.SMS_CREATE_DATE,'YYYY-MM-DD HH24:MI:SS') CREATE_DATE,
TO_CHAR(T.SMS_PUSH_DATE,'YYYY-MM-DD HH24:MI:SS') PUSH_DATE,
T.SCH_LEVEL FROM SMS_PUSH T
WHERE T.SMS_ID IN(
SELECT * FROM(SELECT A.SMS_ID
FROM SMS_PUSH A
WHERE 1=1
AND A.SMS_PUSH_STATE IS NULL
<isNotEmpty property="userType">
AND A.SMS_TYPE = #userType#
</isNotEmpty>
<isNotEmpty property="pushTime">
AND TO_CHAR(A.SMS_PUSH_DATE,'YYYY-MM-DD HH24:MI:SS') < #pushTime#
</isNotEmpty>
ORDER BY A.SMS_ID)WHERE ROWNUM <= $maxCount$
) FOR UPDATE NOWAIT SKIP LOCKED
@Override
public void run() {
// 注入DAO
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
messageMgrFacadeImpl = (MessageMgrFacadeImpl) context
.getBean("doone-education-messageMgrFacade");
searchMap.put("pushTime", DateUtil.getCurrentTimeFull());
searchMap.put("maxCount", Config.getInstance().getMaxCount());
// 获取未发送信息记录
synchronized (this) {
List list = messageMgrFacadeImpl.findPushList(searchMap);
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
HashMap listMap = (HashMap) list.get(i);
System.out.println("++++==" + i + ":" + listMap);
//......接口操作
HashMap<String, Object> search = new HashMap<String, Object>();
search.put("smsId", smsId);
search.put("errorCode", returnResult);
search.put("errorMsg", ReturnMessage.getInstance()
.getMsgByCode(returnResult));
// 保存返回信息
messageMgrFacadeImpl.insertPushLog(search);
}
} else {
// 休息1s
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log4jInitialize.logger(ManagerThread.class).error(
"Pusher.run方法异常:" + e);
e.printStackTrace();
}
}
}
}
我把有关操作全放入一个锁,但是还是出现一样的问题!public synchronized List findPushList(HashMap searchMap)
这里加不行么?public class ManagerThread extends Thread {
private volatile boolean stop = false;
private final LinkedList<Thread> sendThreadList = new LinkedList<Thread>();
private static final Object sendLock = new Object();
private int sendThreadCount = 1;
public ManagerThread() {
this.setDaemon(true);
}
public ManagerThread(int sendThreadCount) {
this.sendThreadCount = sendThreadCount;
this.setDaemon(true);
}
@Override
public void run() {
while (!stop) {
try {
synchronized (sendLock) {
for (int i = 0; i < sendThreadList.size(); i++) {
Thread t = sendThreadList.get(i);
if (t.getState() == Thread.State.TERMINATED) {
sendThreadList.remove(i);
break;
}
}
if (sendThreadList.size() < this.sendThreadCount) {
Pusher p = new Pusher();
Thread t = new Thread(p);
t.start();
sendThreadList.add(t);
}
}
// 睡眠30s
TimeUnit.SECONDS.sleep(30);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void myStop() {
synchronized (sendLock) {
for (int i = 0; i < this.sendThreadList.size(); i++) {
Thread t = sendThreadList.get(i);
if (t != null) {
t.stop();
}
}
this.sendThreadList.clear();
}
this.stop = true;
}
}
sendThreadCount是设定的线程数
public class PushMain {
private ManagerThread tm;
private boolean stop = false;
public void start()
{
tm = new ManagerThread(Config.getInstance().getSendThreadCount());
tm.start();
}
public void stop()
{
if (tm != null){
tm.myStop();
}
stop = true;
}
}
task
PushMain pushMain = new PushMain();
pushMain.start();