Solved Problem while querying MySQL DB in a different Thread

Discussion in 'Spigot Plugin Development' started by tarpers, Apr 26, 2017.

  1. Hello,

    I have a problem and I know why it is occuring however I am not sure how to fix it:

    Code (Text):
        public int getBoosters(final UUID uuid) {

            Bukkit.getScheduler().runTaskAsynchronously(PlayerTimer.getInstance(), new Runnable() {
                @Override
                public void run() {
                    try {
                        Connection connection = PlayerTimer.getInstance().getHikari().getConnection();
                        PreparedStatement selectBooster = connection.prepareStatement(SELECTBOOSTER);
                        selectBooster.setString(1, uuid.toString());
                        ResultSet result = selectBooster.executeQuery();
                        if (result.next()) {
                            System.out.println(result.getInt("boosters"));
                            boosters.put(uuid, result.getInt("boosters"));
                        } else {
                            boosters.put(uuid, -1);
                        }
                        result.close();
                        connection.close();
                    } catch (SQLException e) {
                        boosters.put(uuid, -1);
                        e.printStackTrace();
                    }


                }
            });
           //Returns null
            return boosters.get(uuid);
        }
    It is returning the booster.get(uuid) straight away (And therefor returns null) and not waiting for the query (As it's using another thread). I was just wondering how I would return the value most efficiently.

    Thanks,
     
  2. Try checking out this thread https://www.spigotmc.org/threads/getting-info-from-mysql-asynchronously.8517/
     
    • Like Like x 1
    • Informative Informative x 1
  3. A way that you could make this work is by using Aikar's TaskChain library, its a library that allows you to switch synchronisation contexts easily, you could use this to switch to async, query the db, switch to sync and return.

    Another solution would be to use and return a Future<T> instead of just T

    Sent from my Nexus 5 using Tapatalk
     
    • Like Like x 1
  4. I believe the problem here is that the task isn't being completed in time, then you're calling
    Code (Text):
    return boosters.get(uuid);
    which hasn't been populated by your async code.

    Two ways you can work with this: http://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/ (which I used to create receivers to run tasks after another), Aikar's method (posted above) or use a SyncDelayedTask and put something like 10 ticks to delay the getter (although this might not always be consistent, if the mysql transaction lasts longer than 10 ticks, you'll still return a null).

    Goodluck!
     
    • Like Like x 1
  5. Thanks to all who has posted,
    Ive solved it using the Future method
    Pretty good video here on anyone else who finds this thread and is stuck


    Thanks,
     
    • Winner Winner x 1