主线程中shutdownNow()之后的org.h2.jdbc.JdbcSQLException

时间:2017-09-29 12:52:29

标签: java multithreading jdbc

我有ExecutorService(线程池大小= 4)处理多个Callables。它们每个都打开一个数据库连接(Hikari连接池)并再次关闭它。

如果我现在在ExecutorService上调用shutdownNow(),我也会等待当前正在运行的任务的终止。但是,尽管awaitTermination没有产生超时 - 因此所有正在运行的任务应该已经终止,并且所有数据库操作都应该已经完成​​ - 我得到org.h2.jdbc.JdbcSQLException说明以下内容:

General error: "java.lang.IllegalStateException: Reading from nio:database.mv.db failed; file length -1 read length 256 at 711665 [1.4.196/1]"; SQL statement: SELECT * FROM PERSON WHERE id = ? [50000-196]

此外,我关闭Hikari连接池要比关闭ExecutorService要晚。你有什么想法我可以搜索吗?

编辑:

这是基本的代码结构 - 我想我已经提到了所有必要的项目。请注意,所提到的异常不会每次都被抛出 - 但大部分时间都是这样:

class DatabaseManager {
    private HikariDataSource datasource;
    private static DatabaseManager instance;
    public static DatabaseManager getInstance() { 
        if (instance == null) {
            instance = new DatabaseManager();
        }
        return instance;
    }
    public Connection getConnection() { datasource.getConnection(); }
    private DatabaseManager() {
        // initialize with parameters for a H2 database
        this.datasource = new HikariDataSource();
    }
    public void shutdown() {
        if (this.datasource != null) {
            this.datasource.shutdown();
        }
        this.datasource = null;
    }
}

class SimpleCallable extends Callable<SomeType> {
    String information;
    public SomeCallable(String info) { this.information = info; }
    public SomeType call() {
        // omitted try-catch
        Connection connection = DatabaseManager.getInstance().getConnection();
        // doing some things with connection (reading and writing data), the Method invoked is static and synchronized
        // within this method the exception mentioned above is thrown
        SomeType someType = SomeTypeHelper.transferToDB(connection, information);
        connection.close();
        return someType;
    }
}

class SimpleTask extends Runnable {
    public void run() {
        ExecutorService service = new Executors.newFixedThreadPool(4);
        for (i=0; i<1000; i++) {
            SimpleCallable callable = new SimpleCallable("random text");
            FutureTask task = new FutureTask(callable);
            service.submit(task);
        }
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            // nothing to do
        }
        service.shutdownNow();
        try {
            if (!service.awaitTermination(60, TimeUnit.SECONDS)) {
                System.out.println("timeout"); // but will never be printed
            }
        }
        catch (InterruptedException e) {
            // nothing to do
        }
    }
}

class App {
    public static void main(String[] args) {
        SimpleTask task = new SimpleTask();
        new Thread(task).start();
        DatabaseManager.getInstance().shutdown();
    }
}

0 个答案:

没有答案