如何正确加载播放器数据并避免获取旧数据
How to load playerdata correctly and avoid it from getting the old data
我的 bungeecord 服务器网络有问题。
基本上,当我从 MySQL 数据库加载播放器数据时,我遇到的问题如标题中所述,它加载旧数据而不是保存在 PlayerQuitEvent
上的新播放器数据(PlayerKickEvent
) 然后几乎立即在另一台服务器的 PlayerJoinEvent
上重新加载。
以下是您可以重现问题的步骤:
- 使用 2 个服务器和 SQL 方法设置 bungeecord 网络:
- 在
PlayerQuitEvent
(玩家切换到另一台服务器)将一些数据存储到MySQL数据库中(示例:等级:VIP)
问题:由于数据不会立即更新,因此会加载玩家退出事件前的旧数据
- on
PlayerJoinEvent
(玩家切换到另一台服务器)加载存储在 PlayerQuitEvent 上的数据
我的代码:
保存方式:
public void saveFields(String uuid, Map<String, String> fields) {
for (final String s : fields.keySet()) {
if (s.equalsIgnoreCase("uuid")) continue;
if (s.equalsIgnoreCase("id")) continue;
createColumn(database + "_data", s);
sendUpdateQuery("UPDATE " + database + "_data SET " + s + "='" + fields.get(s) + "' WHERE uuid='" + uuid + "'");
}
}
加载方式:
public Map<String, String> getFields(String uuid) {
Map<String, String> map = new HashMap<>();
ResultSet rs = null;
PreparedStatement st = null;
try {
st = con.prepareStatement("SELECT * FROM " + database + "_data WHERE uuid=?");
st.setString(1, uuid);
rs = st.executeQuery();
for (String colum : getColumns(rs)) {
rs.first();
if (rs.getRow() != 0) {
map.put(colum, rs.getString(colum));
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeResources(rs, st);
}
closeResources(rs, st);
return map;
}
这种行为称为竞争条件。 MySQL is a bad database and therefore has this problem. 为了解决这个问题,你必须在玩家重新登录的第二个事件中使用合理的中继进行查询,或者强制玩家在重新登录之前等待(这是小游戏代理服务器采用的一种方法),但它是最有效的方法是放弃 MySQL 并使用合适的数据库。
我的 bungeecord 服务器网络有问题。
基本上,当我从 MySQL 数据库加载播放器数据时,我遇到的问题如标题中所述,它加载旧数据而不是保存在 PlayerQuitEvent
上的新播放器数据(PlayerKickEvent
) 然后几乎立即在另一台服务器的 PlayerJoinEvent
上重新加载。
以下是您可以重现问题的步骤:
- 使用 2 个服务器和 SQL 方法设置 bungeecord 网络:
- 在
PlayerQuitEvent
(玩家切换到另一台服务器)将一些数据存储到MySQL数据库中(示例:等级:VIP)
问题:由于数据不会立即更新,因此会加载玩家退出事件前的旧数据
- on
PlayerJoinEvent
(玩家切换到另一台服务器)加载存储在 PlayerQuitEvent 上的数据
我的代码: 保存方式:
public void saveFields(String uuid, Map<String, String> fields) {
for (final String s : fields.keySet()) {
if (s.equalsIgnoreCase("uuid")) continue;
if (s.equalsIgnoreCase("id")) continue;
createColumn(database + "_data", s);
sendUpdateQuery("UPDATE " + database + "_data SET " + s + "='" + fields.get(s) + "' WHERE uuid='" + uuid + "'");
}
}
加载方式:
public Map<String, String> getFields(String uuid) {
Map<String, String> map = new HashMap<>();
ResultSet rs = null;
PreparedStatement st = null;
try {
st = con.prepareStatement("SELECT * FROM " + database + "_data WHERE uuid=?");
st.setString(1, uuid);
rs = st.executeQuery();
for (String colum : getColumns(rs)) {
rs.first();
if (rs.getRow() != 0) {
map.put(colum, rs.getString(colum));
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeResources(rs, st);
}
closeResources(rs, st);
return map;
}
这种行为称为竞争条件。 MySQL is a bad database and therefore has this problem. 为了解决这个问题,你必须在玩家重新登录的第二个事件中使用合理的中继进行查询,或者强制玩家在重新登录之前等待(这是小游戏代理服务器采用的一种方法),但它是最有效的方法是放弃 MySQL 并使用合适的数据库。