Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix issue xerial#90: Timeout handling is incompatible with Hibernate
The handling of the queryTimeout in JDBC3Statement was not compliant to the JDBC specification in several ways, breaking Hibernate: * The queryTimeout was being applied to the whole connection, as soon as setQueryTimeout was called, and never set back. So setting the timeout on a single statement would affect the whole connection, even if the statement was about to be discarded (and thus its queryTimeout should have been irrelevant). The fix now only applies the timeout to the connection if and when the statement is actually executed, and resets it to the connection's original setting after the statement is done (using a try-finally block). * A queryTimeout of 0 was translated to a busyTimeout of 0, which is not correct, because JDBC defines a queryTimeout of 0 to mean "there is no limit" (i.e., wait forever), whereas for SQLite, a busy_timeout of 0 means "do not wait at all", i.e., the exact opposite. We now only forward non-zero query timeouts to the connection. If queryTimeout=0 (the default), we keep the connection's default busyTimeout. * The getQueryTimeout method was returning a value in milliseconds rather than seconds. This is now fixed simply by returning the internal queryTimeout variable, which is in seconds. (That change was necessary anyway because we no longer always set the connection's timeout.) The first two issues together were breaking Hibernate because, for some reason, whenever Hibernate closes a Statement, the last thing it does before calling close() on the Statement is that it calls setQueryTimeout(0) on it. This was being misinterpreted as a setBusyTimeout(0) on the entire Connection. As a result, later requests on the same connection did not handle concurrency at all. (Hibernate treats the "database is locked" exception as basically a fatal error.) While Hibernate's behavior is strange, I think it is compliant to the JDBC specification, and SQLite-JDBC was doing the wrong thing. Fixing either of the two issues would have been enough to make Hibernate work, but this patch addresses both, so that we do what the JDBC documentation says. Fixes xerial#90.
- Loading branch information