Je rencontre des problèmes de chargement/stockage de données MySQL, ceci est mon codeParfait pour utiliser les données MySQL mise à jour/stockage sans retard et d'erreurs à la mise à jour des statistiques
public void loadPlayer(Player p) {
if (isPlayerInDataBase(p)) {
Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), new Runnable() {
@Override
public void run() {
Connection connection = sql.getConnection();
try {
PreparedStatement select = connection
.prepareStatement("SELECT * FROM `MurderData` WHERE playername='" + p.getName() + "'");
ResultSet result = select.executeQuery();
if (getPlayerData(p) != null) {
while (result.next()) {
getPlayerData(p).setdeaths(result.getInt("deaths"));
getPlayerData(p).setkills(result.getInt("kills"));
getPlayerData(p).setwins(result.getInt("wins"));
getPlayerData(p).setlose(result.getInt("loses"));
getPlayerData(p).setscore(result.getInt("score"));
getPlayerData(p).setcoins(result.getInt("coins"));
}
CloseResultSet(result);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
});
} else {
Connection connection = sql.getConnection();
Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), new Runnable() {
@Override
public void run() {
try {
PreparedStatement insert = connection.prepareStatement(
"INSERT INTO `MurderData` (playername, wins, deaths, loses, kills, coins, score) VALUES (?, ?, ?, ?, ?, ?, ?)");
insert.setString(1, p.getName());
insert.setInt(2, 0);
insert.setInt(3, 0);
insert.setInt(4, 0);
insert.setInt(5, 0);
insert.setInt(6, 0);
insert.setInt(7, 0);
insert.executeUpdate();
ClosePreparedStatement(insert);
} catch (SQLException e) {
e.printStackTrace();
}
}
public boolean isPlayerInDataBase(Player p) {
Connection connection = sql.getConnection();
try {
PreparedStatement select = connection
.prepareStatement("SELECT * FROM `MurderData` WHERE playername='" + p.getName() + "'");
ResultSet result = select.executeQuery();
if (result.next()) {
CloseResultSet(result);
return true;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
La question est donc essentiellement, devrais-je fermer les instructions préparées après la mise à jour des données MySQL? et devrais-je faire cela avoir un retard comme le fermer après 5 secondes? puis-je optimiser ce code pour le rendre meilleur?
Le joueur est dans la base de données, n'est-ce pas?
ceci est mon 2 méthodes de fermeture:
public void CloseResultSet(ResultSet s) {
new BukkitRunnable() {
@Override
public void run() {
if (s != null) {
try {
s.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.runTaskLater(this, 20 * getConfig().getInt("close-sql-statements-after"));
}
public void ClosePreparedStatement(PreparedStatement s) {
new BukkitRunnable() {
@Override
public void run() {
if (s != null) {
try {
s.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.runTaskLater(this, 20 * getConfig().getInt("close-sql-statements-after"));
}
Mise à jour: il est le deuxième problème, le premier problème est les petites pointes de lag deuxième problème est le stockage de données en ligne 252
public void setSQLData(Player p, int kills, int deaths, int loses, int wins, int coins, int score) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
Connection connection = plugin.sql.getConnection();
try {
PreparedStatement insert = connection.prepareStatement(
"INSERT INTO `MurderData` (playername, wins, deaths, loses, kills, coins, score) VALUES (?, ?, ?, ?, ?, ?, ?)");
insert.setString(1, p.getName());
insert.setInt(2, wins);
insert.setInt(3, deaths);
insert.setInt(4, loses);
insert.setInt(5, kills);
insert.setInt(6, coins);
insert.setInt(7, score);
insert.executeUpdate();// error line 252
plugin.ClosePreparedStatement(insert);
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at java.lang.reflect.Constructor.newInstance(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.Util.handleNewInstance(Util.java:407)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3082)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2968)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3516)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2111)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2407)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2325)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2310)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at me.joseph.murder.api.MurderAPI$1.run(MurderAPI.java:252)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:71)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at java.lang.Thread.run(Unknown Source)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2529)
[22:31:18] [Craft Scheduler Thread - 71/WARN]: at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2979)
Au lieu de fonctionner de cette façon, syncronously avec fil conducteur de Bukkit, exécutez dans un fil asynchrone, ce qui en fait le fond. Il ne devrait pas verrouiller votre serveur, ne causant ainsi pas de retard – Kerooker
De même, exécuter une requête dans 'isPlayerInDataBase (Player p)', puis réexécuter exactement la même requête s'il est dans la base de données semble un peu redondant. Utilisez simplement les données que vous avez obtenues lors de la vérification. – Solarflare
Cela pourrait être complètement hors base, mais une autre façon (en dehors des deux mentionnés par Kerooker et Solarflare) pour aider le lag est (avec des ressources système permettant) de mettre en cache les joueurs récents qui partent, donc s'ils reviennent bientôt vous n'avez plus besoin de récupérer leurs données. Maintenant, cela ne ferait que rendre les choses plus rapides si vous avez les ressources du système le permettent, et si ce n'est pas le cas, cela pourrait ralentir les choses. Maintenant, la mise en cache est une pratique courante. Cependant, je ne sais pas à quel point cela est vrai pour mysql ou bukkit/minecraft. –