- 103
- 0
我这边有个项目,是使用客户端socekt 连接服务获取数据并保存到数据库,但是由于是一个客户端连接多个服务,目前只想到了多线程,但是在线程下一直无法保存数据会是什么原因导致的
private JdbcTemplate jdbcTemplate = null;
private InputStream in;
private Socket socket = null;
private String ip = null;
private int port = 0;
private ProductionDataRepository repository;
private JSONObject json = null;
private ProductionData SelectProdata = null;
private int connect_Info_id = 0;
private int a = 1;
private int b = 2;
public SaveDataThread(String ip,int port,ProductionDataRepository repository,ProductionData SelectProdata,int connect_Info_id,JdbcTemplate jdbcTemplate) throws UnknownHostException, IOException {
this.port = port;
this.ip = ip;
this.repository = repository;
this.SelectProdata = SelectProdata;
this.connect_Info_id = connect_Info_id;
this.jdbcTemplate = jdbcTemplate;
socket = new Socket(ip, port);
}
@Transactional(rollbackOn=Exception.class)
public synchronized void run() {
System.out.println("线程-" + Thread.currentThread().getId());
System.out.println(ip);
System.out.println(port);
ProductionData Prodata = null;
boolean connectStatus = true;
while(connectStatus) {
try {
if(socket.getInputStream() == null) {
continue;
}
in = socket.getInputStream();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
socket.sendUrgentData(0xFF);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
socket = null;
connectStatus = false;
}
byte[] data=new byte[1024];
int len = 0;
try {
len = in.read(data);
} catch (IOException e) {
System.out.println("ProductionDataServices的save方法中的in.read(data)调用异常,异常原因:"+e.getMessage());
e.printStackTrace();
}
System.out.println(new String(data,0,len));
json = JSONObject.fromObject(new String(data,0,len));
/*json = getPorductionData(as.get("ip").toString(),Integer.parseInt(as.get("port").toString()));*/
if(json == null) {
System.out.println("json对象为 null,未获取到数据!");
continue;
}
//查询生产数据id 等于 production_data_id的数据
//获取
//如果当天存在数据则对数据进行修改
String state = null;
if(SelectProdata != null) {
// 0 暂停 1 运行 2 未连接
if(json.getInt("State") == 0) {
state = "暂停";
} else if(json.getInt("State") == 1) {
state = "运行";
}
//判断是否为空,防止未连接时存在对象但是开始时间为空
if(SelectProdata.getStartTime() == null) {
repository.updateStart_time(new Timestamp(System.currentTimeMillis()),SelectProdata.getId());
}
System.out.println();
int OK = SelectProdata.getOk()+json.getInt("OK");
System.out.println("对象ng: "+SelectProdata.getOk());
System.out.println("json对象NG: "+json.getInt("OK"));
System.out.println(""+SelectProdata.getOk()+"+"+json.getInt("OK")+"="+(SelectProdata.getOk()+json.getInt("OK")));
System.out.println("int总和ng: "+OK);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
String sql = "update ss_production_data pd set "
+ "pd.ok = "+(SelectProdata.getOk()+json.getInt("OK"))+","
+ "pd.ng = "+(SelectProdata.getNg()+json.getInt("NG"))+","
+ "pd.total = "+(SelectProdata.getOk()+json.getInt("OK")+SelectProdata.getNg()+json.getInt("NG"))+","
+ "pd.state = '"+state+"',"
+ "pd.owe_hole = "+(SelectProdata.getOweHole()+json.getInt("Hole"))+","
+ "pd.long_hair = "+(SelectProdata.getLongHair()+json.getInt("LongHair"))+","
+ "pd.Long_short_hair="+(SelectProdata.getLongShortHair()+json.getInt("UnevenHair"))+","
+ "pd.loose_wool="+(SelectProdata.getLooseWool()+json.getInt("LooseHair"))+","
+ "pd.implantation_error ="+(SelectProdata.getImplantationError()+json.getInt("WrongHair"))+","
+ "pd.difference_hair = "+(SelectProdata.getDifferenceHair()+json.getInt("CrushHair"))+","
+ "pd.dirty= "+(SelectProdata.getDirty()+json.getInt("Dirt"))+","
+ "pd.end_time = '"+df.format(new Date())+"'"
+ "where pd.id = "+SelectProdata.getId()+"";
save(sql);
continue;
}
Prodata = new ProductionData();
//否则因为不存在id修改将变成添加
Prodata.setName(connect_Info_id+"号机器");//机器名称
Prodata.setConnectInfoId(connect_Info_id);//绑定连接信息id
Prodata.setOk(json.getInt("OK"));//合格
Prodata.setNg(json.getInt("NG"));//不合格
Prodata.setTotal((json.getInt("OK")+json.getInt("NG")));//总数
// 0 暂停 1 运行 2 未连接
if(json.getInt("State") == 0) {
Prodata.setState("暂停");
} else if(json.getInt("State") == 1) {
Prodata.setState("运行");
}
Prodata.setOweHole(json.getInt("Hole"));//欠孔
Prodata.setLongHair(json.getInt("LongHair"));//长毛
Prodata.setLongShortHair(json.getInt("UnevenHair"));//长短毛
Prodata.setLooseWool(json.getInt("LooseHair"));//散毛
Prodata.setImplantationError(json.getInt("WrongHair"));//植错毛
Prodata.setDifferenceHair(json.getInt("CrushHair"));//差毛
Prodata.setDirty(json.getInt("Dirt"));//脏毛
Prodata.setStartTime(new Timestamp(System.currentTimeMillis()));
Prodata.setStartTime(new Timestamp(System.currentTimeMillis()));
Prodata.setCreateTime(new Timestamp(System.currentTimeMillis()));
repository.save(Prodata);
}
}
public void save(String sql) {
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://127.0.0.1:3306/hair_planting_machine?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true";
String username = "root";
String password = "123456";
Connection conn = null;
try {
Class.forName(driver); //classLoader,加载对应驱动
conn = (Connection) DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
int i = 0;
PreparedStatement pstmt;
try {
pstmt = (PreparedStatement) conn.prepareStatement(sql);
i = pstmt.executeUpdate();
System.out.println("resutl: " + i);
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} - 共 0 条
- 全部回答
-
时光划破青春 普通会员 1楼
在多线程环境下,通常情况下是无法直接操作数据库的,因为数据库通常是由多个不同的线程或进程共享的。这些线程或进程共享同一套数据库系统,它们需要访问数据库的资源,如表、索引、存储过程、触发器等,这些资源是互斥的,也就是说,一个线程不能同时访问同一个数据库表中的所有数据,而另一个线程也不能同时访问同一数据库表中的任何一条数据。
然而,可以使用数据库的数据库访问接口(如SQL API)在多线程环境下操作数据库。以下是一些使用数据库API操作数据库的基本步骤:
- 获取数据库连接:在多线程环境中,你需要使用数据库的API来获取数据库连接,这通常涉及到在主程序中创建一个数据库连接对象,然后在其他线程中使用这个连接对象来执行数据库查询。
java Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password");- 执行SQL查询:在获取数据库连接后,你可以使用SQL API执行查询。例如,你可以使用
Statement对象来执行SQL查询,PreparedStatement对象来执行预编译的SQL查询,以及ResultSet对象来获取查询结果。
java Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM mytable");- 获取结果集中的数据:使用
ResultSet对象获取查询结果,然后遍历这个结果集,获取每条数据并对其进行处理,如插入、更新或删除等。
java while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); // 处理数据... } rs.close(); stmt.close(); conn.close();- 提交更改:如果查询结果中存在需要修改的记录,你可能需要提交更改,这通常涉及到使用
PreparedStatement对象执行一个更新操作。例如,你可以使用以下代码向表中添加一条新的记录:
java PreparedStatement pstmt = conn.prepareStatement("INSERT INTO mytable (id, name) VALUES (?, ?)"); pstmt.setInt(1, 100); pstmt.setString(2, "John Doe"); pstmt.executeUpdate();- 处理错误:在执行任何操作时,都可能会出现错误。你需要在每次执行操作后捕获并处理可能的错误,如
SQLException、ConnectionException、PreparedStatementException等,以避免程序崩溃。
java try { // 执行操作... } catch (SQLException e) { e.printStackTrace(); } catch (ConnectionException e) { e.printStackTrace(); } catch (PreparedStatementException e) { e.printStackTrace(); }需要注意的是,虽然在多线程环境下可以使用数据库API操作数据库,但直接修改数据库表中的数据可能会导致数据不一致,因此在进行大规模数据操作时,通常会采取分表、缓存、事务等方式来保证数据的一致性和完整性。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部

