如何正确加载播放器数据并避免获取旧数据

How to load playerdata correctly and avoid it from getting the old data

我的 bungeecord 服务器网络有问题。

基本上,当我从 MySQL 数据库加载播放器数据时,我遇到的问题如标题中所述,它加载旧数据而不是保存在 PlayerQuitEvent 上的新播放器数据(PlayerKickEvent ) 然后几乎立即在另一台服务器的 PlayerJoinEvent 上重新加载。

以下是您可以重现问题的步骤:

问题:由于数据不会立即更新,因此会加载玩家退出事件前的旧数据

我的代码: 保存方式:

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 并使用合适的数据库。