Witam !
Tworzę pewną aplikację, w której wiele wątków wkłada do bazy kolejne rekordy. Korzystam z Embedded Derby, które jest załączone do JDK.
W tym miejscu zamieszczam kod obsługujący połączenie się z bazą oraz operację wstawienia:

public class DatabaseConnection
{
    private static String dbURL = "jdbc:derby:./Database/DB;create=true;user=fafejs;password=fafejs";
    private Connection conn;
    private DatabaseUpdateContent duc;
    private DatabaseUpdateView duv;

    public synchronized void createConnection()
    {
        try
        {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); // load the driver
            conn = DriverManager.getConnection(dbURL); // make Derby JDBC connection
            duc = new DatabaseUpdateContent(conn);
            duv = new DatabaseUpdateView(conn);
            System.out.println(conn);
        }
        catch (Exception except) // TODO - obsluga
        {
            except.printStackTrace();
        }
    }

    public synchronized void recreateConnection()
    {
        try
        {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            conn = DriverManager.getConnection(dbURL);
            duc = new DatabaseUpdateContent(conn);
            duv = new DatabaseUpdateView(conn);
            System.out.println("Reconnect:" + conn);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }

   public boolean updatePlayer(PlayerService player)
    {
        try
        {
            int ID = player.getID();
            String firstName = player.getFirstName();
            String lastName = player.getLastName();
            Date birthdate;
            if(!(player.getDate() == null))
                birthdate =  new java.sql.Date(player.getDate().getTime());
            else
                birthdate = null;
            String league = newLeagueName(player.getLeagueName()).toUpperCase();
            String team = player.getTeamName();
            int apps = player.getApps();
            int firstSquad = player.getFirstSquad();
            int minutes = player.getMinutes();
            int goals = player.getGoals();
            int yellowCards = player.getYellowCards();
            int redCards = player.getRedCards();
            duc.updatePlayersTable(ID, firstName, lastName, birthdate);
            duc.updateLeagueTable(league, ID, team, apps, firstSquad, minutes, goals, yellowCards, redCards);
            return true;
        }
        catch (SQLException sqlExcept)
        {
            //shutdown();
            sqlExcept.printStackTrace();
            return false;
        }
    }
   
   public synchronized void shutdown()
   {
        try
        {
            DriverManager.getConnection(dbURL + ";shutdown=true");
            conn.close();
            //System.gc();
        }
        catch (SQLException sqlExcept)
        {
            //sqlExcept.printStackTrace();
        }
    }
}

    public void updatePlayersTable(int ID, String firstName, String lastName, Date birthdate) throws SQLException // z klasy DatabaseUpdateContent
    {
        PreparedStatement pstmt = conn.prepareStatement("UPDATE APP.PLAYERS SET FIRST_NAME = ?, LAST_NAME = ?, BIRTHDATE = ? WHERE ID = ?");
        pstmt.setString(1,firstName);
        pstmt.setString(2,lastName);
        pstmt.setDate(3,birthdate);
        pstmt.setInt(4,ID);
        if(pstmt.executeUpdate() == 0)
        {
            pstmt = conn.prepareStatement("INSERT INTO APP.PLAYERS VALUES (?,?,?,?)");
            pstmt.setInt(1, ID);
            pstmt.setString(2, firstName);
            pstmt.setString(3, lastName);
            pstmt.setDate(4, birthdate);
            pstmt.execute();
        }
        pstmt.close();
    }

public void updateDB() // procedura, która zajmuje się aktualizacją zawartości bazy danych
{
        DatabaseConnection database = new DatabaseConnection();
        database.createConnection();
        for(PlayerService player: players)
        {
            while(!database.updatePlayer(player))
            {
                database.recreateConnection();
            }
        }
        database.shutdown();
}

Generalnie znaczna ilość rekordów jest wstawiana do odpowiedniej tabeli bez problemu, ale czasem wystąpi wyjątek java.sql.SQLNonTransientConnectionException:

java.sql.SQLNonTransientConnectionException: No current connection.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.noCurrentConnection(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.checkIfClosed(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.setupContextStack(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
	at DatabaseService.DatabaseUpdateContent.updateLeagueTable(DatabaseUpdateContent.java:39)
	at DatabaseService.DatabaseConnection.updatePlayer(DatabaseConnection.java:68)
	at DataService.TeamService.updateDB(TeamService.java:66)
	at DataService.TeamService.getPlayers(TeamService.java:56)
	at DataService.TeamService.getPlayersUrls(TeamService.java:44)
	at DataService.LeagueService.getTeams(LeagueService.java:52)
	at DataService.LeagueService.run(LeagueService.java:35)
	at java.lang.Thread.run(Thread.java:745)
Caused by: ERROR 08003: No current connection.
	at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
	... 17 more
java.sql.SQLException: Database './Database/DB' not found.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.handleDBNotFound(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.<init>(Unknown Source)
	at org.apache.derby.jdbc.InternalDriver.getNewEmbedConnection(Unknown Source)
	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
	at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
	at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:270)
	at DatabaseService.DatabaseConnection.recreateConnection(DatabaseConnection.java:35)
	at DataService.TeamService.updateDB(TeamService.java:69)
	at DataService.TeamService.getPlayers(TeamService.java:56)
	at DataService.TeamService.getPlayersUrls(TeamService.java:44)
	at DataService.LeagueService.getTeams(LeagueService.java:52)
	at DataService.LeagueService.run(LeagueService.java:35)
	at java.lang.Thread.run(Thread.java:745)
Caused by: ERROR XJ004: Database './Database/DB' not found.
	at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.wrapArgsForTransportAcrossDRDA(Unknown Source)
	... 20 more

Ten błąd występuje, że tak powiem cyklicznie, ponieważ jeśli nie uda mi się zaktualizować gracza to w funkcji updatePlayer jest zwracana wartość false i następuje kolejny obieg pętli w procedurze updateDB, który polega na ponownym utworzeniu połączenia - recreateConnection();. Co ciekawe, po pewnym czasie (zazwyczaj po jakiś ok 50 próbach wstawienia rekordu) udaje się utworzyć połączenie i zostaje wsadzony ten rekord.
Oczywiście szukałem rozwiązania tego problemu i znalazłem, żeby użyć System.gc(), aby zmusić garbage collector przy kończeniu połączenia do pozbycia się sterownika do bazy Embedded Derby, aby można go było później jeszcze raz "wgrać" przy tworzeniu kolejnego połączenia. Niestety, ten zabieg nie pomógł.
Wydawało mi się, że występujący błąd może mieć związek z tym, że wiele wątków próbuje wrzucić swoje rekordy do bazy. Jednak, czytałem w dokumentacji, że Embedded Derby powinno sobie z tym radzić (jakby co tych wątków jest dokładnie na tą chwilę 10).

Z góry dziękuje za pomoc.