db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dag H. Wanvik" <dag.wan...@oracle.com>
Subject Re: Thread-safe shutdown while other threads might try to reopen
Date Tue, 01 Oct 2013 14:20:55 GMT
Hi,

I don't believe this situation has changed since 10.8. I agree this 
situation could be improved, so I suggest filing an improvement request 
in JIRA. It would also help if you could supply a self contained repro 
(not strictly necessary, as I believe the description is clear enough, 
but it might just increase the chance of some developer looking at it...)

Thanks,
Dag

On 01. okt. 2013 11:57, Trejkaz wrote:
> Hi all.
>
> We have an application where there are multiple different contexts and
> each is isolated from the others (like a webapp). Individual users
> close and open databases at will. They're opening their own database
> instance rather than sharing an instance directly, in an attempt to
> improve the isolation.
>
> When all users have disconnected from the database, the admin expects
> to be able to move the database files aside, so we have to shut the
> database down when nobody is connected to it.
>
> To try and achieve that, we keep our own static reference count. This
> is done somewhat like this (only the real version uses ConcurrentMap,
> so there is a lot more boilerplate):
>
>      public class Database {
>          private static final Map<String, Integer> connectionCountMap =
>              new HashMap<String, Integer>();
>          private static final Object connectionCountLock = new Object();
>
>          private final String path;
>          private final Connection conn;
>
>          public Database(String path) throws SQLException {
>              this.path = path;
>              conn = DriverManager.getConnection("jdbc:derby:" + path);
>          }
>
>          public void close() throws SQLException {
>              conn.close();
>              decConnectionCount(path);
>          }
>
>          public void incConnectionCount(String path) {
>              Integer count = connectionCountMap.get(path);
>              if (count == null) {
>                  count = 1;
>              }
>              connectionCountMap.put(path, count + 1);
>          }
>
>          public void decConnectionCount(String path) {
>              Integer count = connectionCountMap.get(path);
>              int countAfterDec = count - 1;
>              if (countAfterDec > 0) {
>                  connectionCountMap.put(path, countAfterDec);
>              } else {
>                  connectionCountMap.remove(path);
>                  try {
>                      DriverManager.getConnection("jdbc:derby:" + path +
>                           ";shutdown=true");
>                  } catch (SQLException e) { /* expected */ }
>              }
>          }
>      }
>
> What we are finding is that if multiple threads are accessing the same
> database like this, sometimes one of them will be in the middle of
> opening a connection while another thread is shutting down the
> database. I ended up debugging this into Derby and found that the
> thread opening the database would get a null database reference. Derby
> would then throw an exception saying the database not found.
>
> So the end result is that despite the database files existing on disk,
> Derby would report that the database was not found, which is wrong in
> itself...
>
> Anyway, setting the incorrect exception message aside, it seems like
> Derby is thread-hostile in this regard. The docs do say only to
> shutdown when you know the JVM won't open the database again. The
> problem with this is that you never know that, so you can never shut
> it down--so the files never get unlocked.
>
> I know I can just slap a synchronized block around these two methods
> to make it bulletproof, but there are two problems with this:
>    (1) synchronized is slow and Derby's shutdown is not fast at all...
>    (2) I don't know what other apps might be open in the same JVM at the same.
>
> So I wonder if anyone with experience in this sort of thing has any
> good tips on how to get around the problem.
>
> Also, we're on Derby 10.8, so if anything has been improved in this
> regard in the later releases, that would be good to know - it might
> just be enough impetus to switch.
>
> TX


Mime
View raw message