2012-04-05 11 views
0

Ich habe zwei Quartz (1.8.3) Jobs, konfiguriert über Spring (2.5.6), einer von ihnen schreibt (send) in die Datenbank, und man liest davon (prüfen).Lesen/Schreiben von Quartz-Jobs in die Datenbank - Transaktionen funktionieren nicht

<bean id="scheduleFactory" 
     class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
    <property name="triggers"> 
     <list> 
      <ref bean="Check"/> 
      <ref bean="Send"/> 
     </list> 
    </property> 
</bean> 

<bean id="Send" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
    <property name="jobDetail"> 
     <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
      <property name="targetObject" ref="StatusMonitor" /> 
      <property name="targetMethod" value="sendMessage" /> 
     </bean> 
    </property> 
    <property name="cronExpression" value="0 0/1 * * * ?" /> 
</bean> 

<bean id="Check" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
    <property name="jobDetail"> 
     <bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
      <property name="targetObject" ref="StatusMonitor" /> 
      <property name="targetMethod" value="checkAndUpdateStatus" /> 
     </bean> 
    </property> 
    <property name="cronExpression" value="30 0/1 * * * ?" /> 
</bean> 

Transaktionsmanager eingerichtet ist:

<tx:annotation-driven transaction-manager="TransactionManager"/> 

In beiden Jobs, die ich in Transaktionen wie dies ausdrücklich lesen Run/Schreiboperationen:

@Override 
    public synchronized void sendMessage() { 
     try { 
      TransactionTemplate tt = new TransactionTemplate(ptm); 
      tt.execute(new TransactionCallbackWithoutResult() { 
       @Override 
       protected void doInTransactionWithoutResult(TransactionStatus status) { 
        ... 
        statusDAO.update(status); 
        ... 
       } 
      }); 
      log.info("Status was updated"); 
     } catch (Exception e) { 
      ... 
     } 
    } 

wo ew eine Transaction Bean ist, injiziert über den Frühling. Ich sehe "Status wurde aktualisiert" Datensatz in Protokollen, aber wenn ich diesen Datensatz von transaktionalen Lese-Methode gelesen, ist es manchmal veraltet. Außerdem, wenn ich einen SQL-Editor verwende, um diesen Datensatz zu lesen, ist es auch veraltet. Ich verstehe nicht, warum Transaktionen in diesem Fall nicht funktionieren, haben Sie irgendwelche Ideen? Danke.

+0

Ist 'statusDAO' transactional (dh mit der @Transactionnal Annotation zum Beispiel)? –

+0

Haben Sie dieses Problem immer noch? –

+0

Wenn das Problem "manchmal" auftritt (aber die Protokollnachricht jedes Mal gedruckt wird), bedeutet dies höchstwahrscheinlich, dass Ihre Persistenzlogik fehlerhaft ist (JDBC oder Hibernate?). Überprüfen Sie den Inhalt der Funktion "doInTransactionWithoutResult" mit allen verschachtelten Aufrufen. Ich brauche mehr Code, um genauer zu sein. Wenn Sie ein minimales Testisolierungsproblem erstellen könnten, wird es helfen. –

Antwort

1

Für alle, die interessiert sein könnten. Dieser arbeitete für mich

<bean name="applicationDataCollectorControllerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> 
    <property name="jobClass" value="org.mypckage.controller.jobs.ApplicationDataCollectorController" /> 
    <property name="jobDataAsMap"> 
     <map> 
      <!--<entry key="timeout" value="1" />--> 
      <entry key="genericService" value-ref="genericService" /> 


      <entry key="applicationDataCollectorService" value-ref="applicationDataCollectorService" /> 

      <entry key="transactionManager" value-ref="transactionManager" /> 

     </map> 
    </property> 



</bean> 

--- im Scheduler Bohne ---

@Override 
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { 

getApplicationDataCollectorService().collectData(transactionManager); 


} 

---- Im applicationDataCollectorService Bohne -----

public void collectData(org.springframework.transaction.jta.JtaTransactionManager transactionManager) { 



     try { 
      this.transactionManager = transactionManager; 
      testTransactionalSave(); 

     } catch (Exception e) { 
      BUSY = false; 
      e.printStackTrace(); 
     } 

    } 

} 

private void testTransactionalSave() throws Exception { 

    TransactionTemplate tt = new TransactionTemplate(transactionManager); 
    tt.execute(new TransactionCallbackWithoutResult() { 
     @Override 
     protected void doInTransactionWithoutResult(TransactionStatus ts) { 
      try { 
       ApplicationParameter appPara = null; 
       List<ApplicationParameter> appParaList = genericService.getListFromHQL("select o from ApplicationParameter as o order by o.id desc", false); 
       if (appParaList != null) { 
        if (appParaList.size() > 0) { 
         appPara = (ApplicationParameter) appParaList.get(0); 
         appPara.setLastBankStatementMailNum(appPara.getLastBankStatementMailNum() + 10); 

         appPara = (ApplicationParameter) genericService.mergeObject(appPara); 

         System.out.println(" num is now = " + appPara.getLastBankStatementMailNum()); 
        } 
       } 
      } catch (Exception ex) { 
       ex.printStackTrace(); 

      } 
     } 
    }); 

} 

Hinweis: Vergessen Sie nicht transactionManager als private Eigenschaften in beiden Beans mit public setter und getter für den Frühling zu deklarieren. Irgendwelche Fragen? [email protected]

Verwandte Themen