Java 应用程序中的 SQLite 崩溃(在线游戏)
SQLite Crash In Java Application (Online Game)
我正在为在线游戏编写插件。它在 MS Server 2012 上 运行ning。该插件通过扩展开发人员 API 提供的 @EventMethods 来工作,我的插件使用 SQLite 数据库来存储与游戏相关的玩家信息 "chunks"(环境中的 3D 空间)。
在我的测试服务器上一切正常,但只有我自己和其他用户对其进行了测试。
当我将插件部署到主服务器并且人们开始加入(大约 12 个用户)时,服务器在大约十分钟后崩溃并显示 "A fatal error has been detected by the Java Runtime Environment: 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 这样的 "proper" 数据库,并且是否有适当的结构来停止 EXCEPTION_ACCESS_VIOLATION?
编辑:我已经删除了前面代码中重用的 ResultSet 对象(将对象命名为 rs、rs2、rs3 等),但是 Java 运行时环境仍然崩溃并出现 EXCEPTION_ACCESS_VIOLATION在明显的随机基础上(我在整个代码中添加了 println 语句,希望追踪崩溃发生的位置——但它确实看起来是随机的)。有时服务器会 运行 10 分钟然后崩溃,其他时候它会 运行 24 小时左右然后崩溃。我还将所有 ResultSet 包含在 try-with-resources 块中。同样的结果。
不要将 ResultSet 对象 rs 重复用于多个查询,为每个查询创建一个新实例以避免出现问题。
我正在为在线游戏编写插件。它在 MS Server 2012 上 运行ning。该插件通过扩展开发人员 API 提供的 @EventMethods 来工作,我的插件使用 SQLite 数据库来存储与游戏相关的玩家信息 "chunks"(环境中的 3D 空间)。
在我的测试服务器上一切正常,但只有我自己和其他用户对其进行了测试。
当我将插件部署到主服务器并且人们开始加入(大约 12 个用户)时,服务器在大约十分钟后崩溃并显示 "A fatal error has been detected by the Java Runtime Environment: 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 这样的 "proper" 数据库,并且是否有适当的结构来停止 EXCEPTION_ACCESS_VIOLATION?
编辑:我已经删除了前面代码中重用的 ResultSet 对象(将对象命名为 rs、rs2、rs3 等),但是 Java 运行时环境仍然崩溃并出现 EXCEPTION_ACCESS_VIOLATION在明显的随机基础上(我在整个代码中添加了 println 语句,希望追踪崩溃发生的位置——但它确实看起来是随机的)。有时服务器会 运行 10 分钟然后崩溃,其他时候它会 运行 24 小时左右然后崩溃。我还将所有 ResultSet 包含在 try-with-resources 块中。同样的结果。
不要将 ResultSet 对象 rs 重复用于多个查询,为每个查询创建一个新实例以避免出现问题。