With SQLite default isolation level should be set to serializable
See original GitHub issueHi.
I started experimenting with Quartz and use it with sqlite. I have following config:
configure thread pool info
quartz.scheduler.instanceName = MyScheduler
quartz.threadPool.threadCount = 3
quartz.scheduler.instanceId = AUTO quartz.threadPool.threadPriority = Normal
configure for database
quartz.jobStore.type = Quartz.Impl.AdoJobStore.JobStoreTX, Quartz quartz.jobStore.tablePrefix = QRTZ_ quartz.jobStore.clustered = false
quartz.jobStore.lockHandler.type = Quartz.Impl.AdoJobStore.SimpleSemaphore, Quartz
quartz.jobStore.lockHandler.type = Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz quartz.jobStore.driverDelegateType = Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz quartz.jobStore.useProperties = true
quartz.jobStore.selectWithLockSQL = SELECT * FROM {0} LOCKS UPDLOCK WHERE LOCK_NAME = @ lockName
quartz.jobStore.dataSource = myDS quartz.dataSource.myDS.connectionString = data source=f:\GIT\Geodesy\JavadGeoComponents\QuartzTest.db;foreign keys=true;synchronous=Full;default timeout=50; providerName=“System.Data.SQLite” quartz.dataSource.myDS.provider =SQLite-10
And simple code which create HelloWorldJob if there is no stored jobs. Initially I start with empty db. And I usually get this exception:
[2015-03-11 23:11:29,468] [ERROR SchedulerError] Quartz.Core.ErrorLogger {An error occurred while scanning for the next trigger to fire.}
Quartz.JobPersistenceException: Couldn’t acquire next trigger: database is locked
database is locked —> System.Data.SQLite.SQLiteException: database is locked
database is locked
в System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
в System.Data.SQLite.SQLiteDataReader.NextResult()
в System.Data.SQLite.SQLiteDataReader…ctor(SQLiteCommand cmd, CommandBehavior behave)
в System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
в System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior)
в System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
в Quartz.Impl.AdoJobStore.StdAdoDelegate.UpdateTriggerStateFromOtherState(ConnectionAndTransactionHolder conn, TriggerKey triggerKey, String newState, String oldState) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\StdAdoDelegate.cs:строка 1316
в Quartz.Impl.AdoJobStore.JobStoreSupport.AcquireNextTrigger(ConnectionAndTransactionHolder conn, DateTimeOffset noLaterThan, Int32 maxCount, TimeSpan timeWindow) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 2515
— Конец трассировки внутреннего стека исключений —
в Quartz.Impl.AdoJobStore.JobStoreSupport.AcquireNextTrigger(ConnectionAndTransactionHolder conn, DateTimeOffset noLaterThan, Int32 maxCount, TimeSpan timeWindow) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 2543
в Quartz.Impl.AdoJobStore.JobStoreSupport.<>c__DisplayClass66.<AcquireNextTriggers>b__64(ConnectionAndTransactionHolder conn) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 2414
в Quartz.Impl.AdoJobStore.JobStoreSupport.ExecuteInNonManagedTXLock[T](String lockName, Func2 txCallback, Func
3 txValidator) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 3548
в Quartz.Impl.AdoJobStore.JobStoreSupport.AcquireNextTriggers(DateTimeOffset noLaterThan, Int32 maxCount, TimeSpan timeWindow) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 2413
в Quartz.Core.QuartzSchedulerThread.Run() в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Core\QuartzSchedulerThread.cs:строка 290 [See nested exception: System.Data.SQLite.SQLiteException (0x80004005): database is locked
database is locked
в System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
в System.Data.SQLite.SQLiteDataReader.NextResult()
в System.Data.SQLite.SQLiteDataReader…ctor(SQLiteCommand cmd, CommandBehavior behave)
в System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
в System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior)
в System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
в Quartz.Impl.AdoJobStore.StdAdoDelegate.UpdateTriggerStateFromOtherState(ConnectionAndTransactionHolder conn, TriggerKey triggerKey, String newState, String oldState) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\StdAdoDelegate.cs:строка 1316
в Quartz.Impl.AdoJobStore.JobStoreSupport.AcquireNextTrigger(ConnectionAndTransactionHolder conn, DateTimeOffset noLaterThan, Int32 maxCount, TimeSpan timeWindow) в F:\GIT\Geodesy\Test\Lib\Quartz.NET-2.3.1\src\Quartz\Impl\AdoJobStore\JobStoreSupport.cs:строка 2515]
I think that is it problem is with transactions and it’s isolation level. If in file JobStoreSupport.cs, in method GetConnection() in following code:
if (TxIsolationLevelSerializable)
{
tx = conn.BeginTransaction(IsolationLevel.Serializable);
}
else
{
// default
tx = conn.BeginTransaction(IsolationLevel.ReadCommitted);
}
change isolation level to always be Serializable than everything is ok.
Maybe I’m doing something wrong, there are porblems with my Quartz configuration?
System.Data.SQLite.dll version is 1.0.92.0.
Also, AFAIK, sqlite support serializable and read uncommitted isolation levels.
Thanks in advance.
Issue Analytics
- State:
- Created 9 years ago
- Comments:10 (1 by maintainers)
Top GitHub Comments
I think I have found the easy way to solve the problem(thanks @sharov-am 's solution)
add
quartz.jobStore.txIsolationLevelSerializable=true
to config file!Yes it seems reasonable to default to serializable isolation level with SQLite. Now auto-detected and fixed to true when initializing job store.