Программа предназначена для частого запуска фоновых потоков и загрузки входящих DataEvents на удаленный сервер.
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Singleton
@Component
public class RWDataUploader {
protected org.slf4j.Logger log = LoggerFactory.getLogger(RWDataUploader.class);
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
private final Object objectUploaderMonitor = new Object();
private boolean isActive = true;
private int errorCount = 0;
private long sleepTime = 20000l;
private Timer bgProcessTimer;
@PostConstruct
public void init() {
log.info("RWDataUploadClient initilized {} ", RWDataUploader.this);
TimerTask task = new TimerTask() {
@Override
public void run() {
log.info("Staring Upload process...");
RWDataUploader.this.startUpload();
bgProcessTimer.cancel();
}
};
bgProcessTimer = new Timer("Upload process");
bgProcessTimer.scheduleAtFixedRate(task, 10000, 3000); // start with a delay
}
@PreDestroy
public void close() {
stopUpload();
log.info("RWDataUploadClient closed {} ", RWDataUploader.this);
}
public void stopUpload() {
isActive = false;
synchronized (objectUploaderMonitor) {
objectUploaderMonitor.notify();
}
}
public void startUpload() {
while (isActive) {
synchronized (objectUploaderMonitor) {
try {
uploadTxnToServer();
log.debug("UploadTxnToServer Done Sleeping for next cycle " + sleepTime);
objectUploaderMonitor.wait(sleepTime);
} catch (Exception ex) {
errorCount++;
log.error("Exception at ObjectUploaderMonitor.wait " + ex.getMessage() , ex);
if (errorCount == 1) {
isActive = false;
}
}
}
}
log.info("Uploader client is stopped");
}
@Transactional
private void uploadTxnToServer() {
List<RWDataEvent> openDevnts = getPendingDataEvents();
for (RWDataEvent openDevnt : openDevnts) {
log.info("Uploaded DE {} ", openDevnt);
// logic Upload event to remote server
// upload done
openDevnt.setProcessedStatusCode("UPLOADED");
em.merge(openDevnt);
}
}
private List<RWDataEvent> getPendingDataEvents() {
Query nq = em.createNamedQuery("RWDataEvent.findByProcessedStatusCode");
nq.setParameter("processedStatusCode", "WAIT_UPLOAD");
return nq.getResultList();
}
}
Получение следующей ошибки при выполнении
ОШИБКА crrcuploader.RWDataUploader - Исключение в ObjectUploaderMonitor.wait Нет EntityManager с фактической транзакцией, доступной для текущего потока - не может надежно обработать вызов «слияния».springframework.orm.jpa. SharedEntityManagerCreator.java: 106) в com.retailwave.rwos.compartment.uploader.RWDataUploader.startUpload (RWDataUploader.java:82) в com.retailwave.rwos.compartment.uploader.RWDataUploader $ 1.run (RWDataUploader.java:57)