Выполнение нескольких запросов (вставка и обновление) в одной транзакции с использованием шаблона Spring JDBC - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь обновить строку в таблице A и вставляю строку в таблицу B. Это должно произойти в одном вызове. Я использую Spring JDBC для достижения этой цели.

Пример кода

@Transactional
    public boolean approveTenant(ApproveTenantRequest approveTenantRequest) throws ApplicationException {
        LogUtil.debug(logger, "UserManagementDAO - approveTenant - Start");
        try {
            String updateSQL = "UPDATE tenant_master SET isactive=1, last_modified_by=:lastModifiedBy, last_modified_at= now() "
                    + " WHERE tenant_id=:tenantid and tenant_community_id=:cmntId";
            MapSqlParameterSource parameters = new MapSqlParameterSource();
            parameters.addValue("cmntId", approveTenantRequest.getCommunityId());
            parameters.addValue("tenantid", Integer.parseInt(approveTenantRequest.getTenantId()));
            parameters.addValue("lastModifiedBy", approveTenantRequest.getApprovedBy());
            int updateEffectedRows = jdbcTemplate.update(updateSQL, parameters);
            if(updateEffectedRows==1) {
                String insertSql= "INSERT INTO users (username,password,isactive,community_id,userrole,created_by)" + 
                        " values (:username,:password,1,:community_id,:userrole,:created_by)";
                parameters.addValue("username", approveTenantRequest.getEmailId());
                parameters.addValue("password", approveTenantRequest.getEmailId());
                parameters.addValue("community_id", approveTenantRequest.getCommunityId());
                parameters.addValue("userrole", "RESIDENT");
                parameters.addValue("created_by", approveTenantRequest.getApprovedBy());
                int insertEffectedRows = jdbcTemplate.update(insertSql, parameters);
                LogUtil.debug(logger, "UserManagementDAO - approveTenant - End");
                return insertEffectedRows == 0 ? false : true;
            }else {
                throw new ApplicationException("Issue in Approving Tenant, Tenant not exist in master data");
            }
        } catch (DataAccessException dataAccessException) {
            logger.error("Data Access Exception " + dataAccessException);
            throw new ApplicationException(dataAccessException.getMessage());
        } catch (Exception e) {
            logger.error("Exception Occured While approving tenant " + e);
            throw new ApplicationException(e.getMessage());
        }
    }

Есть ли в этом коде недостаток? Это правильный способ сделать? Можете ли вы предложить.

Ответы [ 3 ]

0 голосов
/ 19 января 2019

Я думаю, что ваш ApplicationException является проверенным исключением. Spring не откатит транзакцию, если транзакционный метод по умолчанию выбрасывает проверенное исключение (только не проверено). Но вы можете добавить откат для него вручную следующим образом:

@Transactional(rollbackFor = ApplicationException.class)
0 голосов
/ 19 января 2019

по весне документация

Видимость метода и @ Transactional

При использовании прокси вы должны применить аннотацию @Transactional только для методов с публичной видимостью. Если вы делаете аннотации защищены, закрытые или видимые в пакете методы с аннотацией @Transactional, ошибка не возникает, но аннотированный метод не показывает настроены транзакционные настройки. Рассмотрим использование AspectJ (см. ниже), если вам нужно аннотировать закрытые методы.

0 голосов
/ 18 января 2019

Просто убедитесь, что они относятся к одному методу, который помечен как @Transactional.

Если после второго обновления произойдет сбой, первое будет откатано, и вы сохраните базу данных в согласованном состоянии.

...