0

I have a Spring Service that is going through multiple items in a list and for each one it is making an extra WS call to external services. The Service is called by a Job on a fixed time interval. As a first step, the Service is saving in a JOB_CONTROL table the status of the Job (STARTED), then it iterates through the list and at the end it saves it to (FINISHED).

There are 2 issues:

  1. the JOB_CONTROL table doesn't get saved gradually - only the "FINISHED" value is saved and never "STARTED"
  2. if using flush method in order to force the commit, the table gets locked, eg. no other select can be made on it until the Service finishes

            @Service
    public class PromotionSchedulerService implements Runnable {
    
        @Autowired
        GeofencingAreaDAO storeDao;
    
        @Autowired
        promotionsWSClient promotionsWSClient;
    
        @Autowired
        private JobControlDAO jobControlDAO;
    
        public void run() {
            JobControl job = jobControlDAO.findByClassName(this.getClass().getSimpleName());
    
            job.setState(JobControlStateTypes.RUNNING.getStateType());
            job.setLastRunDate(new Date());
            // LINE BELLOW DOES NOT GET COMMITED IN DB
            jobControlDAO.save(job);
    
            List < GeofencingArea > stores = storeDao.findAllStores();
            for (GeofencingArea store: stores) {
                /** Call WS **/
                GetActivePromotionsResponse rsp = null;
                try {
                    rsp = promotionsWSClient.getpromotions();
                } catch (Exception e) {
                    e.printStackTrace();
                    job.setState(JobControlStateTypes.FAILED.getStateType());
                    job.setLastRunStatus("There was an error calling promagic promotions");
                    jobControlDAO.save(job);
                    return;
                }
    
                List < PromotionBean > promos = rsp.getReturn();
                for (PromotionBean promo: promos) {
                    BackendPromotionPOJO backendPromotionsPOJO = new BackendPromotionPOJO();
                    backendPromotionsPOJO.setDescription(promo.getDescription());
                }
            }
    
    
            // ONLY THIS JOB STATE GOES TO DB. IT ACTUALLY SEEM TO OVERWRITE PREVIOUS SET VALUE ("RUNNING") from line 16
            job.setLastRunStatus("COMPLETED");
            job.setState(JobControlStateTypes.SUCCESS.getStateType());
            jobControlDAO.save(job);
        }
    }
    

I would like to force the commit after changing job state and not locking the table when doing this.

Victor
  • 1,001
  • 2
  • 14
  • 25
  • `flush` isn't a commit. Also creating one large read and doing writes in one go isn't probably the best thing to do. You don't want to have everything in memory at once you want to stream stuff. Everything will be committed in one go as, I suspect, that your `run` method is a single transaction (which in regards of performance isn't very smart either). – M. Deinum Mar 02 '18 at 10:50
  • If multiple transactions come from single session to the same table, one of them will deadlock the table (usually select statement). – Y.Kaan Yılmaz Mar 03 '18 at 00:51
  • I have made some more research and an approach may be https://stackoverflow.com/questions/24338150/how-to-manually-force-a-commit-in-a-transactional-method. – Victor Mar 06 '18 at 09:09

0 Answers0