简体   繁体   English

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

[英]Executing Multiple queries (Insert and Update) in single transaction using Spring JDBC template

I am trying to update a row in table A and inserting a row in table B. This need to be happen in single call. 我正在尝试更新表A中的一行并在表B中插入一行。这需要在单个调用中发生。 I am using spring JDBC to achieve this. 我正在使用Spring JDBC实现此目的。

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

Does this code has any flaw? 这段代码有什么缺陷吗? Is this correct way of doing? 这是正确的做法吗? Can you please suggest. 你能建议一下吗?

Just make sure these are put under one method that is marked as @Transactional . 只要确保将它们放在标记为@Transactional一种方法下即可。

Having that, when the second update fails, the first one will be rolled back and you will keep the database in a consistent state. 这样,当第二次更新失败时,第一个更新将被回滚,您将使数据库保持一致状态。

I think that your ApplicationException is a checked exception. 我认为您的ApplicationException是一个检查的异常。 Spring won't rollback transaction, if transactional method throwed out checked exception by default (only unchecked). 如果默认情况下事务方法抛出检查异常(仅未检查),Spring将不会回滚事务。 But you can add rollback for it manually like this: 但是您可以像这样手动为其添加回滚:

@Transactional(rollbackFor = ApplicationException.class)

As per spring documentation 根据春季文件

Method visibility and @Transactional 方法可见性和@Transactional

When using proxies, you should apply the @Transactional annotation only to methods with public visibility. 使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。 If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. 如果使用@Transactional注释对受保护的,私有的或程序包可见的方法进行注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。 Consider the use of AspectJ (see below) if you need to annotate non-public methods. 如果需要注释非公共方法,请考虑使用AspectJ(请参见下文)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM