В моем приложении потоки переходят в состояние ожидания при доступе к h sql DB для ReentrantReadWriteLock $ NonfairSyn c
Я использую JPA, h sql db 2.3.6, Quartz 2.1.7 для планирования заданий.
Я использовал h sql версии 2.5.0, и такая же проблема возникала очень часто. Итак, на каком-то форуме я нашел решение понизить версию h sql DB до 2.3.6.
Я понизил ее, теперь эта проблема не так часто, но проблема все еще существует. Я также использовал транзакции в API «get», как предлагалось на форумах, но ничего не получалось.
Кто-нибудь может подсказать, неправильно ли я использую h sql или какое-то решение для этой проблемы?
Дамп потока:
"REQUEST_SCHEDULERSERVICE" - Thread t@2051
java.lang.Thread.State: RUNNABLE
at java.io.RandomAccessFile.seek0(Native Method)
at java.io.RandomAccessFile.seek(Unknown Source)
at org.hsqldb.persist.RAFile.readIntoBuffer(Unknown Source)
at org.hsqldb.persist.RAFile.read(Unknown Source)
at org.hsqldb.persist.RAFile.readInt(Unknown Source)
at org.hsqldb.persist.DataFileCache.readObject(Unknown Source)
at org.hsqldb.persist.DataFileCache.getFromFile(Unknown Source)
at org.hsqldb.persist.DataFileCache.get(Unknown Source)
at org.hsqldb.persist.RowStoreAVLDisk.get(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.findNode(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.getLeft(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.getNextRow(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.next(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.findNext(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.next(Unknown Source)
at org.hsqldb.QuerySpecification.buildResult(Unknown Source)
at org.hsqldb.QuerySpecification.getSingleResult(Unknown Source)
at org.hsqldb.QuerySpecification.getResult(Unknown Source)
at org.hsqldb.StatementQuery.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
- locked <1bbad6fe> (a org.hsqldb.Session)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
- locked <1a7770d3> (a org.hsqldb.jdbc.JDBCPreparedStatement)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1002)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:641)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2714)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2667)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:477)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1155)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1114)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:402)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1202)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:468)
at com.MyAPP.scheduler.dataaccess.JobDataStoreDAOImpl.getJobTriggerInstancesByAppJobIds(JobDataStoreDAOImpl.java:525)
at com.MyAPP.scheduler.management.SchedulerManager.getAppTriggerDetailsForJob(SchedulerManager.java:766)
at com.MyAPP.scheduler.management.SchedulerManager.getDataStorePopulatedWithJobTriggerDetailsList(SchedulerManager.java:367)
at com.MyAPP.scheduler.operation.OperationExecuter.getScheduleTriggerDetails(OperationExecuter.java:2244)
at com.MyAPP.scheduler.operation.OperationExecuter.transferData(OperationExecuter.java:2104)
at com.MyAPP.scheduler.service.CIServicization.transferDataSet(CIServicization.java:573)
at com.MyAPP.platformsdk.businesstypes.PlatformSDKManager.transferDataSetRequest(PlatformSDKManager.java:2448)
at com.MyAPP.platformsdk.businesstypes.PlatformSDKManager.processIncomingMessage(PlatformSDKManager.java:1882)
at com.MyAPP.platformsdk.businesstypes.CommunicationManager.process(CommunicationManager.java:985)
at com.MyAPP.platformsdk.businesstypes.CommunicationManager.process(CommunicationManager.java:965)
at com.MyAPP.platformsdk.communicator.rabbitmq.MessageListnerThread.run(RabbitQueue.java:304)
Locked ownable synchronizers:
- locked <3977b95a> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
"MyAPPScheduler_QuartzSchedulerThread" - Thread t@1194
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Native Method)
- waiting to lock <3977b95a> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync) owned by "REQUEST_SCHEDULERSERVICE" t@2051
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(Unknown Source)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(Unknown Source)
at org.hsqldb.persist.DataFileCache.get(Unknown Source)
at org.hsqldb.persist.RowStoreAVLDisk.get(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.findNode(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.getParent(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.getNextRow(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.next(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.findNext(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.next(Unknown Source)
at org.hsqldb.QuerySpecification.buildResult(Unknown Source)
at org.hsqldb.QuerySpecification.getSingleResult(Unknown Source)
at org.hsqldb.QuerySpecification.getResult(Unknown Source)
at org.hsqldb.StatementQuery.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
- locked <1a297031> (a org.hsqldb.Session)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
- locked <4d5b2dab> (a org.hsqldb.jdbc.JDBCPreparedStatement)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectTriggerToAcquire(StdJDBCDelegate.java:2571)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2778)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2755)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3798)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2751)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:264)
Locked ownable synchronizers:
- None
"SchedulerService_EventProcessor_0" - Thread t@764
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Native Method)
- waiting to lock <3977b95a> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync) owned by "REQUEST_SCHEDULERSERVICE" t@2051
at java.util.concurrent.locks.LockSupport.park(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(Unknown Source)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(Unknown Source)
at org.hsqldb.persist.DataFileCache.get(Unknown Source)
at org.hsqldb.persist.RowStoreAVLDisk.get(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.findNode(Unknown Source)
at org.hsqldb.index.NodeAVLDisk.getLeft(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL.next(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.getNextRow(Unknown Source)
at org.hsqldb.index.IndexAVL$IndexRowIterator.next(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.findNext(Unknown Source)
at org.hsqldb.RangeVariable$RangeIteratorMain.next(Unknown Source)
at org.hsqldb.StatementDML.executeUpdateStatement(Unknown Source)
at org.hsqldb.StatementDML.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
- locked <14df7ab7> (a org.hsqldb.Session)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
- locked <7052afbc> (a org.hsqldb.jdbc.JDBCPreparedStatement)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:885)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:957)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:630)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:296)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:271)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.updateAll(DatasourceCallQueryMechanism.java:835)
at org.eclipse.persistence.queries.UpdateAllQuery.executeDatabaseQuery(UpdateAllQuery.java:154)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
at org.eclipse.persistence.queries.ModifyAllQuery.executeInUnitOfWork(ModifyAllQuery.java:148)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeUpdate(QueryImpl.java:298)
at com.MyAPP.scheduler.dataaccess.JobDataStoreDAOImpl.updateReplacedJobTriggersInstances(JobDataStoreDAOImpl.java:314)
at com.MyAPP.scheduler.jobs.ScheduleJobManager.updateTriggerDetailDTO(ScheduleJobManager.java:850)
at com.MyAPP.scheduler.jobs.ScheduleJobManager.notifyOperationCompletion(ScheduleJobManager.java:294)
- locked <ffee4f0> (a java.util.LinkedHashMap)
at com.MyAPP.scheduler.jobs.ContainerExecutionJob.processEvent(ContainerExecutionJob.java:135)
- locked <6e4f71fa> (a com.MyAPP.scheduler.jobs.ScheduleJobManager)
at com.MyAPP.scheduler.event.thread.PoolThread.run(PoolThread.java:45)
Locked ownable synchronizers:
- None
Классы DAO:
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="APP_TRIGGER_DETAIL")
public class AppTriggerDetailDTO{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="TRIGGER_ID")
private String id = null;
@Column(name="TRIGGER_NAME")
private String triggerName = null;
@Column(name="SCHEDULER_NAME")
private String schedulerName = null;
@Column(name="JOB_NAME")
private String jobName = null;
@Column(name="JOB_GROUP_NAME")
private String jobGroupName = null;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="START_TIME")
private Date startTime;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="LAST_UPDATED_TIME")
private Date lastUpdatedTime;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="EXECUTION_START_TIME")
private Date executionStartTime;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="END_TIME")
private Date endTime;
@Column(name="INSTANCE_ID")
private String fireInstanceId;
@Column(name="TRIGGER_EVENT")
private String triggerEvent;
@Column(name="INSTR_CODE")
private String triggerInstructionCode;
@Column(name="REQUEST_REPLACED_BY")
private String requestReplacedBy = null;
@Column(name="ERROR_REASON")
private String errorReason;
@Column(name="STATUS")
private String status;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTriggerName() {
return triggerName;
}
public void setTriggerName(String triggerName) {
this.triggerName = triggerName;
}
public String getSchedulerName() {
return schedulerName;
}
public void setSchedulerName(String schedulerName) {
this.schedulerName = schedulerName;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroupName() {
return jobGroupName;
}
public void setJobGroupName(String jobGroupName) {
this.jobGroupName = jobGroupName;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(Date lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
public Date getExecutionStartTime() {
return executionStartTime;
}
public void setExecutionStartTime(Date executionStartTime) {
this.executionStartTime = executionStartTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getFireInstanceId() {
return fireInstanceId;
}
public void setFireInstanceId(String fireInstanceId) {
this.fireInstanceId = fireInstanceId;
}
public String getTriggerEvent() {
return triggerEvent;
}
public void setTriggerEvent(String triggerEvent) {
this.triggerEvent = triggerEvent;
}
public String getTriggerInstructionCode() {
return triggerInstructionCode;
}
public void setTriggerInstructionCode(String triggerInstructionCode) {
this.triggerInstructionCode = triggerInstructionCode;
}
public String getRequestReplacedBy() {
return requestReplacedBy;
}
public void setRequestReplacedBy(String requestReplacedBy) {
this.requestReplacedBy = requestReplacedBy;
}
public String getErrorReason() {
return errorReason;
}
public void setErrorReason(String errorReason) {
this.errorReason = errorReason;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
Методы, участвующие в тупике:
public List<AppTriggerDetailDTO> getJobTriggerInstancesByAppJobIds(List<AppJobId> appJobIds) {
EntityManager entityManager = null;
List<AppTriggerDetailDTO> triggersList = new ArrayList<>();
try {
entityManager = takeEntityManager();
entityManager.getTransaction().begin();
Query query = entityManager
.createQuery("SELECT trigger FROM AppTriggerDetailDTO trigger WHERE trigger.jobName =:jobName and trigger.jobGroupName =:jobGroupName and trigger.schedulerName =:schedulerName");
for (AppJobId appJobId : appJobIds) {
query.setParameter(JOB_NAME, appJobId.getJobName());
query.setParameter(JOB_GROUP_NAME, appJobId.getJobType());
query.setParameter(SCHEDULER_NAME, appJobId.getSchedulerName());
List<AppTriggerDetailDTO> triggersResult = (List<AppTriggerDetailDTO>) query.getResultList();
if (triggersResult != null && triggersResult.isEmpty() == Boolean.FALSE) {
triggersList.addAll(triggersResult);
}
}
entityManager.getTransaction().commit();
} catch (Exception e) {
LOG.error("Exception in getJobTriggerInstancesByJobKey with stacktrace {}", e);
if (entityManager != null) {
entityManager.getTransaction().rollback();
throw new SchedulerServiceRuntimeException(e);
}
} finally {
releaseEntityManager();
}
return triggersList;
}
public void updateReplacedJobTriggersInstances(List<String> replacedContextIds, String jobInstanceId, Date endTime) {
EntityManager entityManager = null;
try {
entityManager = takeEntityManager();
entityManager.setFlushMode(FlushModeType.COMMIT);
entityManager.getTransaction().begin();
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.append("UPDATE AppTriggerDetailDTO dto SET dto.endTime=:endTime, dto.requestReplacedBy=:requestReplacedBy WHERE dto.fireInstanceId IN ('");
gernerteInQuery(replacedContextIds, queryBuilder);
Query query = entityManager.createQuery(queryBuilder.toString());
query.setParameter("endTime", endTime);
query.setParameter("requestReplacedBy", jobInstanceId);
int updated = query.executeUpdate();
LOG.info("Inside updateReplacedJobTriggersInstances, Number of records updated is {}" + updated);
entityManager.getTransaction().commit();
} catch (Exception e) {
LOG.error("Exception in updateReplacedJobTriggersInstances with stacktrace {}", e);
if (entityManager != null) {
EntityTransaction transaction = entityManager.getTransaction();
if (transaction != null && transaction.isActive()) {
transaction.rollback();
}
throw new SchedulerServiceRuntimeException(e);
}
} finally {
releaseEntityManager();
}
}
Конфигурация постоянства
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="scheduler" transaction-type="RESOURCE_LOCAL">
<class>com.MyAPP.scheduler.dto.AppTriggerDetailDTO</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
<property name="javax.persistence.jdbc.url" value = "jdbc:hsqldb:file:../SchedulerService/database/db;hsqldb.tx=mvcc;hsqldb.default_table_type=cached;hsqldb.cache_rows=1000;hsqldb.cache_size=20480;" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
<property name="eclipselink.create-ddl-jdbc-file-name" value="createDDL_ddlGeneration.sql" />
<property name="eclipselink.drop-ddl-jdbc-file-name" value="dropDDL_ddlGeneration.sql" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>