Reputation: 115
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. I am using spring JDBC to achieve this.
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.
Upvotes: 2
Views: 5213
Reputation: 11926
As per spring documentation
Method visibility and @Transactional
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. 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. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
Upvotes: 0
Reputation: 844
I think that your ApplicationException
is a checked exception. Spring won't rollback transaction, if transactional method throwed out checked exception by default (only unchecked).
But you can add rollback for it manually like this:
@Transactional(rollbackFor = ApplicationException.class)
Upvotes: 0
Reputation: 26572
Just make sure these are put under one method that is marked as @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.
Upvotes: 5