DataNucleus выдает исключение при изменении более одного объекта в потоке - PullRequest
1 голос
/ 05 сентября 2011

Я сталкиваюсь с проблемой при изменении объекта в цикле в том же потоке, и модификация, кажется, работает нормально, если изменение выполняется в разных потоках.

Вот код, который я написал для того же.

Вызов родительского метода:

public void task(){
    List<URLTask> tasks = dService.getTasksForStatusReport(System.currentTimeMillis());
    System.out.println("scheduler called to send mail");
    this.sendMail(tasks,false);
}

сервис для извлечения списка задач:

public List<URLTask> getTasksForStatusReport(long timestamp) {
    PersistenceManager pm = pmf.getPersistenceManager();
    Query q = pm.newQuery("SELECT FROM " + URLTask.class.getName() + " WHERE nextMailTimestamp <= "+timestamp+" && isDeleted != true");
    List<URLTask> c = (List<URLTask>)q.execute();
    pm.detachCopyAll(c);//I have tried commenting and uncommenting this line but no effect
    return c;
}

Код для sendMail (tasks, boolean) следующий:

public void sendMail(List<URLTask> tasks , boolean consolidatedEmail){
    for(URLTask task: tasks){
            task.setNextMailTimestamp(System.currentTimeMillis() + task.getMailIntervalInMilliseconds());
            dService.saveUrlTask(task);
        }
    }
}

Метод saveUrlTask ​​(задача):

public URLTask saveUrlTask(URLTask task) {
    PersistenceManager pm = pmf.getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    URLTask taskCopy;
    tx.begin();

    Query q = pm.newQuery("SELECT FROM " + URLTask.class.getName() +
                " WHERE isDeleted != 0 && id == \"" + task.getId() + "\"");
    long bfr = System.currentTimeMillis();
    List<URLTask> taskList = (List<URLTask>)q.execute();
    long aft = System.currentTimeMillis();
    System.out.println("getting url task time = "+ (aft-bfr));

    URLTask oldTask = taskList.get(0);
    oldTask.setRepeatIntervalInSeconds(task.getRepeatIntervalInSeconds());
    oldTask.setUrl(task.getUrl());
    oldTask.setDeleted(task.isDeleted());
    oldTask.setNextMailTimestamp(task.getNextMailTimestamp());
    oldTask.setMailIntervalInMilliseconds(task.getMailIntervalInMilliseconds());
    oldTask.setUserDefinedErrorMessages(task.getUserDefinedErrorMessages());
    oldTask.setUpdateTimeStamp(System.currentTimeMillis());
    oldTask.setMailIntervalInMilliseconds(task.getMailIntervalInMilliseconds());
    oldTask.setNextMailTimestamp(task.getNextMailTimestamp());
    oldTask.setUserDefinedErrorMessages(task.getUserDefinedErrorMessages());

    bfr = System.currentTimeMillis();
    pm.makePersistent(oldTask);
    aft = System.currentTimeMillis();
    System.out.println("updating url task time = "+ (aft-bfr));

    taskCopy = (URLTask)(pm.detachCopy(oldTask));
    tx.commit();
    pm.close();
    return taskCopy;
}

Код отлично работает, когда размер списка равен 1, а размер 2 равен, он снова отлично работает для первого, но выдает исключение при запуске во второй раз.

Для справки, исключение составляет:

Exception in thread "HBase Connection Evictor" java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1768)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatch(HConnectionManager.java:1143)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatchOfPuts(HConnectionManager.java:1241)
at org.apache.hadoop.hbase.client.HTable.flushCommits(HTable.java:826)
at org.apache.hadoop.hbase.client.HTable.close(HTable.java:838)
at org.datanucleus.store.hbase.HBaseManagedConnection.closeTables(HBaseManagedConnection.java:169)
at org.datanucleus.store.hbase.HBaseManagedConnection.dispose(HBaseManagedConnection.java:154)
at org.datanucleus.store.hbase.HBaseConnectionPool.disposeTimedOutConnections(HBaseConnectionPool.java:94)
at org.datanucleus.store.hbase.HBaseConnectionPool.access$000(HBaseConnectionPool.java:27)
at org.datanucleus.store.hbase.HBaseConnectionPool$1.run(HBaseConnectionPool.java:105)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)

Любая форма помощи будет весьма полезна.

Заранее спасибо !!

devsri

...