Quartz scheduler locks database when it fails to connect - java

I'm using Quartz 2.2.2 in clustering mode and Spring 4.2.
I'm facing an issue with Quartz because he locks the DB when it is not able to connect to the DB.
When I say the DB is locked, I mean the DB will locked the profile which is trying to connect with the wrong password for instance. Quartz will try to connect while he's failing, and the DB will lock the profile for safety.
I would like to know if it is possible to limit the connection attempts of Quartz when it fails ?
Quartz.properties :
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 1
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = quartzDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.quartzDS.jndiURL=java:/comp/env/jdbc/E760
Do you have any idea ? I took a look to the quartz's doc' but I did not find something to help me.
There is a similar post to this one there :
Quartz Scheduler locks the database user
But I would like to know if there is/are another way to solve it.
Thanks a lot.

Related

Spring JDBC Hikari constantly logon logoffs in Oracle Database

I am using spring boot hikari db pool to connect to an Oracle database (19C).
Our properties are as below:
spring.datasource.app.hikari.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.app.hikari.minimumIdle=5
spring.datasource.app.hikari.maximumPoolSize=10
spring.datasource.app.hikari.idleTimeout=600000
spring.datasource.app.hikari.connectionTimeout=180000
spring.datasource.app.hikari.max-lifetime=60000
Our Database's AUD table is filling up due to constant logon logoff actions getting registered from the services every second.
I used solution from below question (to decrease minimumIdle and increase idleTimeout for long idle times), but it did not resolve the issue.
spring jdbc hikari connection pool - constantly logs on and off to database
Can somebody help in this case. Thanks in advance.
If you have not override datasource with different property name for hikaricp then use below properties
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.connection-timeout=180000
spring.datasource.hikari.max-lifetime=60000

spring-xd job repository datasource enable oracle fast connection failover

In Spring-XD clustered environment, we are using Oracle as job repository datasource. Right now, this has been configured through servers.yml. But, we have to enable fast connection failover (FCF) for High availability (HA). Does current servers.yml support this? Or Is there a way to replace job repository data source with Oracle Pool DataSource with ONS configuration. Please advise me with any solution?
you should be able to configure your datasource like any spring datasource.
did you try configure the datasource like this http://docs.spring.io/spring-data/jdbc/docs/current/reference/html/orcl.failover.html ?
you have to include your configuration like
datasource:
url: jdbc:"jdbc:oracle:thin:#(description=(address_list=(address=(host=rac1)(protocol=tcp)(port=1521))(address=(host=rac2)(protocol=tcp)(port=1521)))(connect_data=(service_name=racdb1)))"
username: sa
password:
driverClassName: oracle.jdbc.driver.OracleDriver
validationQuery: select 1 from INFORMATION_SCHEMA.SYSTEM_USERS
fast-connection-failover-enabled:true
ONS-configuration="rac1:6200,rac2:6200"
Let me know if that works, I am curious :)

Tomcat connection pool with both Shiro and Postgres

I'm trying to add some efficiency to my web app with Tomcat jdbc connection pool. Currently i have configured it to work with Shiro - it saves logins in Postgres db. But at the same time i have other part of my app that needs to work with Postgres db. Is it possible to configure only one pool to be available both for Shiro and my app?
Part of the shiro.ini about jdbc:
ds = org.apache.tomcat.jdbc.pool.DataSource
ds.driverClassName = org.postgresql.Driver
ds.username = shiroadmin
ds.password = adminshiro
ds.url = jdbc:postgresql://localhost:5432/cleb
jdbcRealm.dataSource = $ds
PS: i'm using tomcat pool as a maven dependency

JNDI issue with Websphere 6 UserTrasaction and Quartz Scheduler

I have my Web Application running on WebSphere 6.0 and also there are some Quartz Scheduler Tasks. If I do the lookup like that in hibernate.cfg.xml:
<property name="jta.UserTransaction">java:comp/UserTransaction</property>
It works fine with my Web Application, but any threads initiated by Quartz Timers fail to access the DB using that lookup string. But if I use
<property name="jta.UserTransaction">jta/usertransaction</property>
Then it is the opposite. I will get quartz timers working but I can't do the lookup inside my Web Application.
Is there any way to make them both work with same hibernate configuration?
EDT: here is my quartz.properties file. By the way Quartz Version is 1.5.2.
org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = one
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 4
org.quartz.jobStore.misfireThreshold = 5000
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
I don't know if this is relevant to you but I recently had a similar problem. My issue was remote and local access and altering my design a bit and adding the interface names to my #Local & #Remote annotations worked for me.
I think you miss the transaction management in your quartz.properties.
Something like this:
org.quartz.scheduler.userTransactionURL=jta/usertransaction
org.quartz.scheduler.wrapJobExecutionInUserTransaction=true
The idea is to tell Quartz to wrap the job execution in a transaction and where to get it.

Spring Framework Connecting JVM with each other

I have 4 servers and JVM is installed on them. I wrote a java service that Quartz calls this services every 10 minutes. But in 4 servers, every 10 minutes 4 calls are done. This sitiuation creates race condition. I want only one service on 4 JVM.
How can I do that with Spring Framework?
This is actually pretty easy to set up with Quartz. Spring itself cannot help you much here since it is unaware of the other JVMs that are running. Quartz on the other hand has the concept of a clustered scheduler.
Basically you need to set up a single database that all the 4 JVMs can share. This will be used as a scheduler for all 4 instances. When a job is scheduled, it is run by only one of the instances using the clustered scheduler.
Taken from the Quartz website wiki for clustering (
http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html), this is an example configuration on how to set up the clustered scheduler. You can also set these properties directly from spring if you are configuring your scheduler that way.
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:#polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
Your question isn't very clear, so let me see if I'm understanding you: you have 4 servers, each running Quartz inside a VM, and each server has the same quartz job scheduled to run every 10 minutes, using a cron expression. Every 10 minutes, all 4 servers kick off the same job, creating your race condition as they all try to do the same thing at the same time.
This isn't really a job for Spring. However, Quartz does have clustering ability, where you configure a job to run only a single server in the cluster. It uses a shared database to coordinate which servers run which job, and makes sure they don't all do it together.
The docs have some info on this here, but in the usual opensymphony.com style they're pretty sparse and unhelpful.
What I do in our web application is for each job to be wrapped in a class that takes out a global lock across your cluster (I use memcached, as I don't really care if the task gets run too often), and only runs the task if it got the lock. It can then release the lock when the task completes (don't forget to do this in a finally).
One advantage of wrapping each job rather than changing the scheduler is that you can have some jobs that run on all the machines, and some that only run on one.

Categories