Question about async: filesystem

80 views
Skip to first unread message

Silvio

unread,
Jul 28, 2022, 7:01:47 AM7/28/22
to H2 Database
This is listed as experimental but I read some posts where this was advertised as a way to prevent database corruption.

What is the risk in using this instead of file: in a production system?

Silvio

unread,
Jul 28, 2022, 7:07:29 AM7/28/22
to H2 Database
And in addition to the above: are there any disadvantages in using async: vs file: ?

Evgenij Ryazanov

unread,
Jul 28, 2022, 8:11:58 AM7/28/22
to H2 Database
Hello!

file: and nio: have no special meaning in modern versions of H2, jdbc:h2:file:SOME_PATH, jdbc:h2:nio:SOME_PATH, and plain jdbc:h2:SOME_PATH have exactly the same meaning.
Unfortunately, invocation of Thread.interrupt() during disk I/O closes the underlying file channel, so it isn't safe to interrupt a thread that executes some database command in embedded persistent database. If you use a separate server process you can interrupt client threads safely.

async: file system uses asynchronous I/O on Windows and it may work a little bit faster, but better performance is not guaranteed for all cases.
On POSIX systems in simply performs I/O in separate threads, so performance may be slightly reduced. These systems, unlike Windows, don't need any special optimizations for multi-threaded access to the same file.
In both cases case Thread.interrupt() on thread that works with database doesn't perform disk I/O by itself, so if you cannot prevent interrupts and cannot use a separate server, you need to use this file system abstraction layer.

Silvio

unread,
Jul 28, 2022, 9:28:18 AM7/28/22
to H2 Database
That sounds clear enough. Since I can not guarantee my databases will not be accessed from threads that may be interrupted (by the servlet container) we have to use async. Thanks for clearing that up.

Evgenij Ryazanov

unread,
Jul 28, 2022, 10:07:47 AM7/28/22
to H2 Database
Web application with embedded database managed by this application must have a ServletContextListener. In its contextDestroyed() method it must shutdown the database properly.

For example, application can use a org.h2.jdbcx.JdbcConnectionPool to allocate its connections. It can be constructed with separately created org.h2.jdbcx.JdbcDataSource.

contextDestroyed() can execute everything you need during unloading of your application first, then it should dispose the connection pool to prevent allocations of new connections by some leftover parts of your application, and finally it must execute the SHUTDOWN command, it can allocate an own connection directly from the data source for this command or use some previously created connection. Possible exceptions from this special connection should normally be ignored.

For Apache Tomcat running as a system service that logic should provide enough safety by itself. But there are other servers and it is possible to launch them in various ways, so in some cases your application may need some additional protection.
Reply all
Reply to author
Forward
0 new messages