没有与数据库的当前连接 - java.sql.SQLNonTransientConnectionException

时间:2016-09-28 21:52:20

标签: java multithreading derby

我正在尝试创建一个多线程应用程序(Java),其中一些线程将更多行插入数据库。我使用JDK的Embedded Derby。

这是与建立数据库连接和插入有关的代码。

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();
}

总的来说,大多数行都被正确地插入到适当的表中,但有时我会得到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

此异常连续多次发生,因为如果更新播放器失败,函数updatePlayer将返回false,我们在函数updateDB中重复循环。但过了一会儿(大约50次插入行的尝试),就可以建立连接并插入一行。

当然我已经找到了解决这个问题的方法。我尝试过与System.gc()相关的方法,在某些文档中提出了什么建议,但在我的情况下没有用。

我还在考虑我的问题可能与我的应用程序的多线程有关,但在Embedded Derby的文档中他们简单地说嵌入式Derby应该处理它。

感谢你的支持。

修改

这是我从http://wiki.apache.org/db-derby/UnwindExceptionChain添加代码后收到的错误信息:

----- SQLException -----
SQLState:   08003
Error Code: 40000
Message:    No current connection.
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.updatePlayersTable(DatabaseUpdateContent.java:17)
at DatabaseService.DatabaseConnection.updatePlayer(DatabaseConnection.java:73)
at DataService.TeamService.updateDB(TeamService.java:64)
at DataService.TeamService.getPlayers(TeamService.java:53)
at DataService.TeamService.getPlayersUrls(TeamService.java:39)
at DataService.LeagueService.getTeams(LeagueService.java:50)
at DataService.LeagueService.run(LeagueService.java:36)
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:39)
at DataService.TeamService.updateDB(TeamService.java:67)
at DataService.TeamService.getPlayers(TeamService.java:53)
at DataService.TeamService.getPlayersUrls(TeamService.java:39)
at DataService.LeagueService.getTeams(LeagueService.java:50)
at DataService.LeagueService.run(LeagueService.java:36)
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

在我看来,与未找到数据库相关的错误(更确切地说,我的意思是与加载嵌入式Derby的驱动程序有关的问题)是由SQLNonTransientConnectionException引起的,并且存在问题。

0 个答案:

没有答案