views:

123

answers:

2

I'm using SQLite (system.data.sqlite v. 1.0.60.0) on a Fluent NHibernate project.

I have one program that writes to the DB, and another that reads from it. Occasionally, I get SQLITE_BUSY exceptions, and I need to fix this.

I found several Google references to sqlite_busy_timeout, which (if I understand correctly) will cause SQLite to re-try before throwing the exception. This would probably be sufficent for my needs.

However, this does not appear to be in the system.data.sqlite assembly.

When I search for SetTimeout using the Object Browser, I get two hits:

System.Data.SQLite.SQLite3.SetTimeout(int)

System.Data.SQLite.SQLiteBase.SetTimeout(int)

but I can't seem to use them in my code - they don't show up in Intellisense, and VS2008 shows a red underline for SQLite3, with the message "Can't access internal class here".

Can anyone give me a sample (in C#) that shows the exact syntax for this method?

Or is this even the right approach? I could probably check for SQLITE_BUSY in my code, but have not found any good examples demonstrating that approach either.

Finally, do Fluent NHibernate or NHibernate have any mechanisms to provide simple shared access to a SQLite database?

+1  A: 

SetTimeout is a member of both NHibernate query interfaces, ICriteria and IQuery.

Example:

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
    var items = session.CreateQuery("select something complex from a big table")
                       .SetTimeout(600) // 10 minutes
                       .List();
    tx.Commit();
}
Diego Mijelshon
@Diego - thanks for your response - I'm going to try this. Also, I phrased my question badly - I actually wanted to set the SQLite timeouts directly. Did a major rewrite - hope it is more clear now.
Tom Bushell
+1  A: 

Just like you said, SetTimeout() is internal, so you (or NHibernate) can't call it. The method only wraps
sqlite_busy_timeout and throws, and you definitely don't want to use those unsafe methods in your application code.

According to this, the SQLite provider should retry for 30 seconds.

Mauricio Scheffer
Thanks! Is there any way I can set the timeout to a shorter interval (say, 5 seconds), to speed up testing?
Tom Bushell
@Tom Bushell: honestly I would recommend using some other DB engine if you need this kind of concurrency. Embedded DB engines are usually not suited for this.
Mauricio Scheffer
Our concurrency requirements are so minimal, it seems that SQLite should be adequate for the job. It's not clear why it's not working yet.
Tom Bushell