使用Spring JDBC模板在单个事务中执行多个查询(插入和更新)

时间:2019-01-18 15:44:10

标签: java spring java-ee spring-jdbc

我试图更新表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 :(得分:2)

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

具有这样的功能,当第二次更新失败时,第一个更新将被回滚,并且您将使数据库保持一致的状态。

答案 1 :(得分:0)

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

@Transactional(rollbackFor = ApplicationException.class)

答案 2 :(得分:0)

每年春天documentation

  

方法可见性和@Transactional

     

使用代理时,应应用@Transactional批注   仅适用于具有公众知名度的方法。如果您做受保护的注释,   带有@Transactional批注的私有或包可见方法   不会引发任何错误,但是带注释的方法不会显示   配置的交易设置。考虑使用AspectJ(请参阅   下面)是否需要注释非公共方法。