I am running a query that looks something like this:
ATTACH 'db2' as db;
BEGIN TRANSACTION;
...
END TRANSACTION;
I have to do it this way because it is an error to attach in the transaction.
The problem appears to occur if another connection is already running any kind of query when the above query is issued. Then the entire query appears to fail, returning SQLITE_BUSY.
To handle this, I sleep for a while and then retry the transaction. However, now I get the error “cannot attach database within transaction”. Why is this happening?
Did the original attach succeed despite returning SQLITE_BUSY? If so, then why didn’t I get “database db2 is already in use” instead? Or is the previous transaction still open despite the fact that SQLITE_BUSY was returned? That doesn’t make sense to me, the query failed busy, so the transaction shouldn’t ever have been opened. But what else could it be?
In general the program performing the query doesn’t know what the query is, it is just a wrapper of sorts. So, I can’t do something like split the query into two parts, one to attach the database and the other to perform the rest of the query. But I’m not sure if this is the problem anyway.
I haven’t figured out exactly why this is happening, but I have found that a satisfactory solution is to call sqlite3_close() followed by sqlite3_open() after SQLITE_BUSY is returned. This gets rid of any outstanding conditions which a retry of the previous query could trip over.