【问题标题】:Executing Multiple queries (Insert and Update) in single transaction using Spring JDBC template使用 Spring JDBC 模板在单个事务中执行多个查询(插入和更新)
【发布时间】:2019-01-18 15:44:09
【问题描述】:

我正在尝试更新表 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());
        }
    }

这段代码有什么缺陷吗?这是正确的做法吗?能否请教一下。

【问题讨论】:

    标签: java spring jakarta-ee spring-jdbc


    【解决方案1】:

    只需确保将它们放在标记为@Transactional 的一种方法下即可。

    这样,当第二次更新失败时,第一次更新将被回滚,您将保持数据库处于一致状态。

    【讨论】:

    • 你能检查我的代码吗?第二次更新插入失败,但第一次更新没有回滚。这里有什么遗漏吗?
    【解决方案2】:

    我认为您的ApplicationException 是一个检查异常。如果事务方法默认抛出检查异常(仅未检查),Spring 不会回滚事务。 但是您可以像这样手动为其添加回滚:

    @Transactional(rollbackFor = ApplicationException.class)
    

    【讨论】:

      【解决方案3】:

      如春documentation

      方法可见性和@Transactional

      当使用代理时,你应该应用@Transactional注解 仅适用于具有公共可见性的方法。如果您确实注释受保护, 带有 @Transactional 注释的私有或包可见方法, 没有引发错误,但带注释的方法没有表现出 配置的事务设置。考虑使用 AspectJ(参见 下面)如果您需要注释非公共方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-24
        • 2013-10-01
        • 2011-08-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-26
        • 1970-01-01
        • 2021-02-28
        相关资源
        最近更新 更多