Управление транзакциями с помощью @@ Transactional Annotation - PullRequest
0 голосов
/ 26 марта 2019

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

Есть 100 записей, для которых я должен сделать выше вставку и обновление. Но если какая-либо запись дает сбой из-за какой-либо ошибки при вставке или обновлении, откат должен выполняться только для этой записи, а не для других. Это означает, что если имеется 100 записей, из которых 60 получает успех, а 61 получает сбой из-за какой-либо ошибки, тогда только 61 запись должна быть откатана, а не все. другие 60 записей.

Я использую Spring boot JPA и @Transactional Annotation.But, если поместить эту аннотацию при запуске моего метода, то в случае любой ошибки она откатит все записи.

Я прилагаю свой код ниже. Пожалуйста, предложите, как я могу добиться этого. В приведенном ниже коде у меня есть метод persistRecord (), в котором есть весь мой код для вставки и обновления. Я не пометил это аннотацией @Transactional, а нижеприведенный метод аннотирован аннотацией @Transactional


        logger.debug("insertSalesTargetData method called of service class");
        String userid = (String) webSession.getAttribute("username");
        logger.debug("Userid :" + userid);
        HashMap<String, String> persistRecordStatus = new HashMap<String, String>();
        Query qCountCheck = em.createNativeQuery(QueryConstant.CHECK_SALES_TARGET_DATA_QUERY);
        List<Object> existingRecordList = null;
        persistRecordStatus.put("TOTAL_RECORD", String.valueOf(xlsRowslist.size()));
        int failedRecordCount = 0;
        int successRecordCount = 0;
        for (int i = 0; i < xlsRowslist.size(); i++) {
            ArrayList rowList = xlsRowslist.get(i);
            // try {
            double weekNoDouble = Double.parseDouble((String) rowList.get(0));// Week No
            String fromDate = (String) rowList.get(1);// fromDate
            String toDate = (String) rowList.get(2);// toDate
            double catCodeDouble = Double.parseDouble((String) rowList.get(3));// catCode
            int catCode = (int) catCodeDouble;
            int weekNo = (int) weekNoDouble;
            String target = (String) rowList.get(4);// target

            String salesGoalId = fromDate + toDate + catCode;
            salesGoalId = salesGoalId.replace("-", "");

            // Check if the sales goal id already exist in the database or not
            qCountCheck.setParameter(1, salesGoalId);// SALES_GOAL_ID
            existingRecordList = qCountCheck.getResultList();
            logger.debug("Count List Size " + existingRecordList.size());
            if (existingRecordList != null && existingRecordList.size() > 0) {
                if (existingRecordList.get(0) != null) {
                    BigDecimal row = (BigDecimal) existingRecordList.get(0);
                    // try {
                    logger.debug("Persisting record no  " + i);
                    persistRecord(row, salesGoalId, target, fromDate, toDate, userid, catCode, weekNo);
                    logger.debug("Record no  " + i + " persisted");
                    persistRecordStatus.put("SUCCESS_RECORD", String.valueOf(successRecordCount++));
                    /*
                     * } catch (Exception e) { persistRecordStatus.put("FAILED_RECORD",
                     * String.valueOf(failedRecordCount++)); }
                     */

                }
            } else {
                persistRecordStatus.put("FAILED_RECORD",String.valueOf(failedRecordCount++));
            }
            /*
             * } catch (Exception e) { logger.debug("Exception in processing record no " + i
             * + " " + e.toString()); persistRecordStatus.put("FAILED_RECORD",
             * String.valueOf(failedRecordCount++)); }
             */

        }
        return persistRecordStatus;
    }

1 Ответ

1 голос
/ 26 марта 2019

Вы делаете какие-то пакетные обновления?

В пакетной обработке вы обрабатываете "сбои", помещая все вовлеченные элементы (например, входную запись, код ошибки, ...) в хранилище ошибок для последующего просмотра некоторым пользователем. И вы делаете это вместе со всеми «успешными» обновлениями.

В качестве альтернативы, поместите каждую пару вставки / обновления в свою собственную транзакцию. (и все же в качестве альтернативы, если ваша СУБД / транзакционная среда поддерживает точки сохранения, возьмите точку сохранения после каждой пары вставки / обновления и после сбоя, откатитесь до последней точки сохранения и затем подтвердите (и найдите способ не потерять оставшиеся 40 необработанных записей из ваш вклад). В любом случае, не приходите жаловаться, если у вас проблемы с производительностью.

В транзакционной пакетной обработке не существует двух вариантов.

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