我的需求是这样的,现在有两个参数手机号和手机内容通过URL传给服务器,他那边有一个接口是接收这两个参数的,
我通过查出我本地的数据将数据通过URL发给服务器,我查多少就传多少,然后放在线程并行执行,但是执行到一段时间tomcat会假死,并没有任何反映,停掉的时候也不报任何异常,大概一个小时左右就停了,这时候我继续敲action地址访问的时候,他会继续执行,不是全新执行,不知道是什么原因,请高手指点,有时候还会报连接失败,dbcomms.receive 方法期间发生异常package com.xhc.business.bo.impl;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;import org.hibernate.Query;import com.xhc.business.bo.base.IDatatransfersBo;
import com.xhc.common.util.ConfigUtil;
import com.xhc.common.util.MessyCodeCheck;
import com.xhc.hibernate.po.TlcLogStddeliver;public class DatatransfersBo extends BaseBo implements IDatatransfersBo { // 常规变量定义
public static final String C1 = "XA";
public static final String C2 = "XB";
public static final String C3 = "XZ";
public static int n = 1;
private int pageSize = 500;
public static int i = 1;
public static Date startDate;
// 返回成功值
static final String SUCCESS = "OK"; public boolean findList() {
startDate = new Date();
// 查表状态为0的所有数据,表示未传
StringBuffer hql = new StringBuffer(
"from TlcLogStddeliver t where 1=1 ");
hql.append(" and t.proStatus='0'");
Query query = getDao().getHibernateTemplate().getSessionFactory()
.getCurrentSession().createQuery(hql.toString());
StringBuffer countHql = new StringBuffer(
"select count(*) from TlcLogStddeliver t where 1=1");
countHql.append(" and t.proStatus ='0' ");
List countList = getDao().find(countHql.toString());
long count = (Long) countList.get(0);
// 循环传输数据的总次数
for (int i = 1; i < count / pageSize; i++) {
List<TlcLogStddeliver> listTable = query.setFirstResult(
(i - 1) * pageSize).setMaxResults(pageSize).list();
if (null != listTable && listTable.size() > 0) {
Thread t = this.createTask(listTable);
t.start();
} }
return true;
} /**
 * 以http get 方式发送参数到相应的uri
 * 
 * @param param
 *            格式 m=?&c=?
 * @param uri
 *            网页地址
 * @return 返回网页内容或错误信息
 */
public static String handlerSendURL(String param, String uri) {
String backStr = "";
HttpURLConnection httpConnection = null;
InputStream input = null;
try {
String urlStr = uri + param;
URL url = new URL(urlStr);
httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setDoOutput(true);
httpConnection.setReadTimeout(10000);
httpConnection.setConnectTimeout(10000);
httpConnection.setRequestMethod("GET");
httpConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
OutputStream os = httpConnection.getOutputStream();
int responseCode = httpConnection.getResponseCode();
if (200 == responseCode) {
input = httpConnection.getInputStream();
} else {
input = httpConnection.getErrorStream();
}
BufferedReader bf = new BufferedReader(new InputStreamReader(input));
StringBuffer sbf = new StringBuffer();
String temp = "";
while ((temp = bf.readLine()) != null) {
sbf.append(temp);
}
backStr = sbf.toString();
input.close();
os.close();
bf.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return backStr;
} public Thread createTask(final List<TlcLogStddeliver> listTable) {
return new Thread() {
public void run() {
for (TlcLogStddeliver table : listTable) {
System.out.println("正在传送当前第" + DatatransfersBo.n + "条数据");
System.out
.println("手机号---------" + table.getVc2srcmobile());
System.out.println("手机内容" + table.getVc2messagecontent()); // 数据库存在乱码更新状态值为1
if (MessyCodeCheck
.isMessyCode(table.getVc2messagecontent())) {
TlcLogStddeliver mb = getDao().findUnique(
TlcLogStddeliver.class, table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
// 手机号为空更新状态值为1
} else if (null == table.getVc2srcmobile()
|| "" == table.getVc2srcmobile()) {
TlcLogStddeliver mb = getDao().findUnique(
TlcLogStddeliver.class, table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
}
// 手机内容为空更新状态值为1
else if (null == table.getVc2messagecontent()
|| "" == table.getVc2messagecontent()) {
TlcLogStddeliver mb = getDao().findUnique(
TlcLogStddeliver.class, table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
}
// 手机内容为XA开始的
else if (null != table.getVc2messagecontent()
&& table.getVc2messagecontent().length() > 5
&& table.getVc2messagecontent().substring(0, 2)
.equals(DatatransfersBo.C1)) {
String XAURL = ConfigUtil.getConfig().getString(
ConfigUtil.XA_URL_PATH);
// URL传参服务器返回状态值
String state = DatatransfersBo.handlerSendURL("m="
+ URLEncoder.encode(table.getVc2srcmobile())
+ "&c="
+ URLEncoder.encode(
table.getVc2messagecontent().substring(
table.getVc2messagecontent()
.lastIndexOf('/') + 1))
.replaceAll("\\+", "%20") + "", XAURL);
// 判断返回状态如果为OK则更新表状态为1
if (state.equals(DatatransfersBo.SUCCESS)) {
TlcLogStddeliver mb = getDao()
.findUnique(TlcLogStddeliver.class,
table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
} else {
System.out.println("服务器接收失败");
// 重新传
DatatransfersBo.i--;
}
}
// 手机内容为XZ开始的将状态置为1
else if (null != table.getVc2messagecontent()
&& table.getVc2messagecontent().length() > 5
&& table.getVc2messagecontent().substring(0, 2)
.equals(DatatransfersBo.C3)) {
TlcLogStddeliver mb = getDao().findUnique(
TlcLogStddeliver.class, table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
}
// 内容为XB开始的将状态置为1
else if (null != table.getVc2messagecontent()
&& table.getVc2messagecontent().length() > 5
&& table.getVc2messagecontent().substring(0, 2)
.equals(DatatransfersBo.C2)) {
String XBURL = ConfigUtil.getConfig().getString(
ConfigUtil.XB_URL_PATH);
// URL传参返回状态值
String state = DatatransfersBo.handlerSendURL("m="
+ URLEncoder.encode(table.getVc2srcmobile())
+ "&c="
+ URLEncoder.encode(
table.getVc2messagecontent().substring(
table.getVc2messagecontent()
.lastIndexOf('/') + 1))
.replaceAll("\\+", "%20") + "", XBURL);
// 判断返回状态如果为OK则更新表状态为1
if (state.equals(DatatransfersBo.SUCCESS)) {
TlcLogStddeliver mb = getDao()
.findUnique(TlcLogStddeliver.class,
table.getNumseqid());
mb.setProStatus("1");
DatatransfersBo.n++;
getDao().update(mb);
} else {
System.out.println("服务器接收失败");
// 重新传
DatatransfersBo.i--;
}
}
Date startDate = new Date();
Date endDate = new Date();
System.out
.println("结束时间: "
+ (new SimpleDateFormat("HH:mm:ss")
.format(endDate)));
System.out.println("总共用多少时间"
+ (endDate.getTime() - DatatransfersBo.startDate
.getTime()) / 1000 + "(秒)"); } }
};
}
}

解决方案 »

  1.   

    看你的问题描述,估计是数据库发生死锁了,多线程操作数据库,要特别注意这个问题。
    代码就不细看了,getDao().update(mb);和getDao().findUnique如果不是同一个事务,可能就会造成死锁
      

  2.   

    不太明白你的意思,控制线程数量,不计算得出,那就自己从配置文件读取,或者用线程池。
    现在你的问题是数据库死锁,你要保证你的每个线程getDao().findUnique的结果是互不重叠,否则getDao().update(mb);后,不能及时提交事务,会造成其他线程的getDao().findUnique死锁。
      

  3.   

    那用什么做啊,spring得到的那个session可以控制在同一事务当中吗