views:

147

answers:

1

I'm developing a project that has multiple programs that share a single, lazy loaded SQLite database file, using Fluent Nhibernate (Auto Mapping) as the data access layer.

The first program I developed (let's call it Program 1) kept the Session open all the time, and lazy loading worked fine.

This approach failed when I got Program 2 running, and tried to write to the database from Program 2 while Program 1 was running - I got "database locked" exceptions.

I got around this by closing the Session after Program 1 starts up - e.g.

        private ISessionFactory _sessionFactory;
        private ISession _session;

        _sessionFactory = Database.CreateSessionFactory();

        _session = _sessionFactory.OpenSession(); 
        _session.BeginTransaction();

        // ... read the database here

        _session.Close();

Of course, this broke lazy loading in Program 1 when the user selected a different data data set from the user interface - which I had expected.

I thought I would be able to just open the Session again whenever the user selected new data, and then close it again - e.g.

        if ( !_session.IsOpen )
            _session = _sessionFactory.OpenSession();

        if ( !_session.IsConnected )
            _session.Reconnect();

        _session.BeginTransaction();

        // ... read the database here

        _session.Close();

But so far, have not been able to get this to work. I get "no session, or session was closed" exception when I try to read the data, even though I've just opened a session. (The test for the connection was just an experiment, because the exception trace said something about throwing lazy exceptions when disconnected, but it didn't help)

What am I doing wrong?

+1  A: 

Is it possible for you to build a service layer which is initiated by the first app to call it (or registered as a windows service if you are on a windows box) and then have everyone call into that service to get their data from?

Im not talking about having a separate server, just a separate service that your programs call into.

GrayWizardx
I suppose, but that would add another layer of complexity, and I'd still have to solve the same problem I have now.
Tom Bushell
Gray Wizard is right...you're duplicating the data access portion between prog1 and prog2. If you create a service that manages the session and exposes query objects for the other two programs you won't run into contention. You could even go crazy and build a SQL parser to turn SQLite into a full DB Server (just kidding)
Mike Brown
Upon reflection, (and reinforced by Mike Brown's comment), I realized you were right. Sorry for being dismissive. I've never written a service - how difficult is it?
Tom Bushell
Its pretty straight forward, depending on the language you are using and the requirements of your scenario. In .NET world you could use something like Named Pipes pretty easily: http://www.switchonthecode.com/tutorials/interprocess-communication-using-named-pipes-in-csharp
GrayWizardx