1
votes

Exécution de plusieurs requêtes (insertion et mise à jour) en une seule transaction à l'aide du modèle Spring JDBC

J'essaie de mettre à jour une ligne dans le tableau A et d'insérer une ligne dans le tableau B. Cela doit se produire en un seul appel. J'utilise Spring JDBC pour y parvenir.

Exemple de code

@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());
        }
    }

Ce code présente-t-il un défaut? Est-ce la bonne façon de faire? Pouvez-vous nous suggérer.


0 commentaires

3 Réponses :


3
votes

Assurez-vous simplement qu'ils sont placés sous une seule méthode marquée comme @Transactional .

Cela dit, lorsque la deuxième mise à jour échoue, la première sera annulée et vous maintiendrez la base de données dans un état cohérent.


1 commentaires

Pouvez-vous vérifier mon code. La deuxième mise à jour n'a pas pu être insérée, mais la première mise à jour n'a pas été annulée. Y a-t-il quelque chose qui manque ici?



0
votes

Je pense que votre ApplicationException est une exception vérifiée. Spring n'annulera pas la transaction, si la méthode transactionnelle a rejeté l'exception cochée par défaut (uniquement non cochée). Mais vous pouvez ajouter une annulation manuellement comme ceci:

@Transactional(rollbackFor = ApplicationException.class)


0 commentaires