Каков наилучший способ написания метода, время выполнения которого более 5 минут? - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть метод Java, который выполняется каждую полночь.Метод выполняет резервное копирование данных из одной таблицы1 в другую таблицу2 и очистку таблицы1.Повседневная таблица1 содержит 13214215 строк.

Это мой метод планировщика

    @Scheduled(cron = "0 59 23 * * *")
    public void doAutoBackupProcess() {

        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");

            HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);

            String url = "http://192.168.31.5:8082/scheduler/attendance/backup/call";

            restTemplate.exchange(url, HttpMethod.GET, entity, Object.class);
            logger.info("Data Backup success");
        } catch (Exception ex) {
            Logger.getLogger(SchedulerService.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

http://192.168.31.5:8082/scheduler/attendance/backup/call содержит метод ниже

    @Transactional
    public void doStdAttendanceBackup() {

        List<StudentAttendanceDetails> sads = studentAttendanceDetailsRepository.findAll();     
        studentAttendanceDetailsBackUpRepository.save(copyStudentAttendanceDetailsToStdAttendanceDetailsBackUp(sads));      
        studentAttendanceDetailsRepository.delete(sads);
    }



public List<StdAttendanceDetailsBackUp> copyStudentAttendanceDetailsToStdAttendanceDetailsBackUp(List<StudentAttendanceDetails> sads) {

        List<StdAttendanceDetailsBackUp> sadbus = sads.stream().map((sad) -> {
            StdAttendanceDetailsBackUp sadbu = new StdAttendanceDetailsBackUp();
            BeanUtils.copyProperties(sad, sadbu);
            return sadbu;
        }).collect(Collectors.toList());
        return sadbus;
    }

Когда выполняется метод Above, тогда я сталкиваюсь с

java.lang.outofmemoryerror gc превышен лимит накладных расходов

и

java.lang.OutOfMemoryError: Пространство кучи Java

Исключение.Я увеличиваю память кучи Java в jvm 2256m, но проблема не решается

Кто-нибудь дает мне лучшее решение?Спасибо

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Решение для резервного копирования всех данных не масштабируется.По этой причине вам следует разбивать на страницы (читать и удалять) больше раз.

boolean migratedElements = false;

//if you delete your data, you can page every time first 1000 records or 10000... this can be tuned
Pageable pageable = new PageRequest(0, 1000);

while(!migratedElements) {

    List<StudentAttendanceDetails> sads1000 = studentAttendanceDetailsRepository.findAll(pageable);  

    if(sads1000.size() == 0) {
        migratedElements = true;
    } else {
        studentAttendanceDetailsBackUpRepository.save(copyStudentAttendanceDetailsToStdAttendanceDetailsBackUp(sads));      
        studentAttendanceDetailsRepository.delete(sads);
    }  

}

Вам также необходимо вызывать службу резервного копирования для каждой страницы, или вы можете встретить ее в outOfMemory

0 голосов
/ 29 сентября 2018

Слишком много методов для его реализации, FYI

  1. JDBC Fetch Stream

Вот пример:

@Autowired
private JdbcTemplate jdbcTemplate;

public void doStdAttendanceBackup() {

    String sql = "select * from *** where c=:c1 and b=:b1";
    jdbcTemplate.setFetchSize(1000); 
    NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);

    Map<String, Object> params = new HashMap<>(2);
    params.put("c1", ***);
    params.put("b1", ***);

    namedParameterJdbcTemplate.query(sql, params, (ResultSet rs) -> {
        // 0. copy rs to StdAttendanceDetailsBackUp;

        // 1. save StdAttendanceDetailsBackUp;

        // 2  delete StudentAttendanceDetails;

        // note: makesure the codes is transactional above
    });
}
Вставить в Select

Пожалуйста, обратитесь: https://www.w3schools.com/sql/sql_insert_into_select.asp

Я думаю, что второй способ лучше для вас, если две таблицы принадлежат одному пользователю БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...