我正在为在线游戏编写插件。它运行在MS Server 2012上。该插件的工作原理是扩展开发人员API提供的@EventMethods,我的插件使用SQLite数据库存储与游戏“块”相关的玩家信息(环境中的3D空间)。
我的测试服务器上的一切都很顺利,但我只有自己和另一个用户测试它。
当我将插件部署到主服务器并且人们开始加入(大约12个用户)时,服务器在大约十分钟后崩溃,并出现“Java运行时环境检测到致命错误:EXCEPTION_ACCESS_VIOLATION”
现在我觉得这是因为SQLite崩溃造成的。
以下是我访问SQLite数据库的一种方法示例。
@EventMethod
public void onPlayerPlaceObject(PlayerPlaceObjectEvent event) throws SQLException {
int blockXChunk = event.getChunkPositionX();
int blockYChunk = event.getChunkPositionY();
int blockZChunk = event.getChunkPositionZ();
String blockChunkID = "" + blockXChunk + blockYChunk + blockZChunk;
try {
//get the playerUID and the blockchunkID
ResultSet rs = database.executeQuery("SELECT * FROM `Areas` WHERE `PlayerUID` = '" + event.getPlayer().getUID() + "' AND `AreaID` = '" + blockChunkID + "'");
if (rs.next() ) {
//player owns chunk do whatever you like!
rs.close();
return;
} rs.close();
//lets see if the blockChunk event is happening somewhere where someone own ths AreaID
rs = database.executeQuery("SELECT * FROM `Areas` WHERE `AreaID` = '" + blockChunkID + "'" );
if (rs.next() ) {
//chunk is owned by someone and its not the one making the event.
String string = (String)rs.getString("PlayerUID");
rs.close();
rs = database.executeQuery("SELECT * FROM `Friends` WHERE `OwnerUID` = '" + string + "' AND `FriendUID` = '" + event.getPlayer().getUID() + "'" );
if (rs.next() ) {
//player is a friend of the owner do whatever you like!
rs.close();
return;
} rs.close();
event.setCancelled(true);
return;
} else { rs.close(); }
} catch ( Exception e ){ System.out.println(); }
}
我怀疑这些方法经常在SQLite数据库上调用,导致它崩溃。有人可以帮我找一个更安全的方式来访问这些数据吗?或者我会更好地使用像MySQL这样的“正确”数据库,并且是否有适当的结构来阻止EXCEPTION_ACCESS_VIOLATION?
编辑:我已经删除了前面代码中重用的ResultSet对象(命名对象rs,rs2,rs3等),但Java Runtime Environment仍然以明显随机的方式使用EXCEPTION_ACCESS_VIOLATION崩溃(我添加了println语句在整个代码中希望追踪崩溃发生的位置 - 但它确实是随机的。有时服务器将运行10分钟并崩溃,有时它将运行24小时左右然后崩溃。我还在try-with-resources块中包含了所有ResultSet。结果相同。
答案 0 :(得分:0)
不要为多个查询重用ResultSet对象rs,为每个查询创建一个新实例以避免出现问题。