Why @Transactional not working in my code?

Multi tool use


Why @Transactional not working in my code?
@Service
public class SingleCityService implements ICityService {
private static final Logger logger = LoggerFactory.getLogger(SingleCityService.class);
@Autowired
CityMmtRepo cityMmtRepo;
@Autowired
MmtCityService mmtCityService;
@Autowired
RestCityService restCityService;
@PostConstruct
public void init() {
CityServiceFactory.getInstance().registor(EnumCity.SINGLE_CITY, this);
}
/**
* Method to validate if action type is to Create city or Update city
*
* @param request
* @return CityServiceResponse
*/
@Override
public CityServiceResponse serveRequest(CityServiceRequest request) throws ResourceException, InvalidCityCreateException, SQLException {
ValidatorFactory.getInstance().getRequestValidator(Validator.SINGLE_CITY_VALIDATOR).validate(request);
if (CityActionType.CREATE.toString().equals(request.getEventType().getActionType())) {
return createCity(request);
}
return updateCity(request);
}
/**
* Method to create city and fetch matched cities from cache.
*
* @param request
* @return CityServiceResponse
* @throws ResourceException
*/
private CityServiceResponse createCity(CityServiceRequest request) throws ResourceException {
logger.info("Inside SingleCityService: Starting createCity for request: {}", request.toString());
/**
* forceUpdate signifies if user still want to create city after getting conflicts.
*/
if (ResourceConstants.TRUE.equalsIgnoreCase(request.getCityDetails().get(0).getForceUpdate())) {
return saveCity(request, ResourceConstants.CREATED);
}
CityCacheServiceResponse cityCacheServiceResponse = restCityService.getCityMatchingFromCityCache(request);
CityServiceResponse cityServiceResponse = new CityServiceResponse();
if (ResourceConstants.FAILURE.equalsIgnoreCase(cityCacheServiceResponse.getStatus())) {
cityServiceResponse.setStatus(ResourceConstants.FAILURE);
cityServiceResponse.setDescription(cityCacheServiceResponse.getDescription());
} else {
if (cityCacheServiceResponse.getCity().get(0).getMatchedCity().isEmpty()) {
return saveCity(request, ResourceConstants.SUCCESS);
} else {
cityServiceResponse.setStatus(ResourceConstants.CONFLICTING_CITIES_UI_DISPLAY_MSG);
cityServiceResponse.setCity(CityServiceMapperUtil.cacheResponse(cityCacheServiceResponse));
}
}
return cityServiceResponse;
}
/**
* To update city.
*
* @param request
* @return CityServiceResponse
* @throws ResourceException
*/
private CityServiceResponse updateCity(CityServiceRequest request) throws ResourceException, InvalidCityCreateException {
logger.info("Inside SingleCityService, Starting updateCity for request: {}", request.toString());
CityMmtEntity cityMmtEntity = mmtCityService.fetchCityToEdit(request.getCityDetails().get(0).getCityCd());
request = CityServiceMapperUtil.mapCityToBeUpdated(cityMmtEntity, request);
return saveCity(request, ResourceConstants.UPDATE);
}
/**
* To create or update city in DB and Push city in Cache.
*
* @param request
* @param status
* @return CityServiceResponse
* @throws ResourceException
*/
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public CityServiceResponse saveCity(CityServiceRequest request, String status) throws ResourceException {
CityMmtEntity cityMmtEntity = CityServiceMapperUtil.getCityEntity(request);
logger.info("Inside SingleCityService: saveCity: Saving city data in DB for cityCode: {}", cityMmtEntity.getChtCitycd());
cityMmtEntity = mmtCityService.SaveToDb(cityMmtEntity);
int i = 1/0;
int k = i;
logger.info("Inside SingleCityService: saveCity: Syncing city to ES API for cityCode: {}", cityMmtEntity.getChtCitycd());
request.getCityDetails().get(0).setCityCd(cityMmtEntity.getChtCitycd());
request.getCityDetails().get(0).setLastUpdatedOn(cityMmtEntity.getChtCityLastUpdDt());
SyncCityCacheRequest syncCityCacheRequest = CityServiceMapperUtil.mapCityCacheRequest(request);
SyncCityCacheResponse syncCityCacheResponse = restCityService.syncCityToCityCache(syncCityCacheRequest);
CityServiceResponse cityServiceResponse = new CityServiceResponse();
cityServiceResponse.setStatus(status);
cityServiceResponse.setDescription(syncCityCacheResponse.getSyncCityDetails().get(0).getDescription());
return cityServiceResponse;
}
}
// I have a method saveCity in my service class as you can see on which I have put @transactional, but it's not working, Database does not roll back on Exception.
// saveToDb is method in another service(below) which is built on Jpa Repository
@Service
public class MmtCityServiceImpl implements MmtCityService {
private static final Logger logger = LoggerFactory.getLogger(MmtCityServiceImpl.class);
@Autowired
private CityMmtRepo cityMmtRepo;
/**
* To save city in DB
*
* @param cityMmtEntity
* @return {@link CityMmtEntity}
*/
public CityMmtEntity SaveToDb(CityMmtEntity cityMmtEntity) throws ResourceException {
try {
logger.info("Inside MmtCityServiceImpl: Starting SaveToDb to save city for CityMmtEntity: {}", cityMmtEntity.toString());
return cityMmtRepo.save(cityMmtEntity);
} catch (Exception e) {
logger.error("MmtCityServiceImpl : Exception while saving/updating city in database, Exception: {}", e);
throw new ResourceException(ResourceErrors.SAVE_CITY_ERROR.getErrorCode(), ResourceErrors.SAVE_CITY_ERROR.getErrorDescription());
}
}
//I put k = 1/0 to throw runtime exception just next to the step where we are saving entity to db just to check if @Transactional working or not, but on exception entity does not roll back from database.
//Actually I am throwing exception from another service (whose method is SyncCityToCache) service is:-
@Service
public class RestCityServiceImpl implements RestCityService {
private static final Logger logger = LoggerFactory.getLogger(RestCityService.class);
@Autowired
RestTemplate restTemplate;
@Value("${rest.elatic-cache-sync.end.point}")
private String cacheSyncEndPoint;
@Value("${rest.elatic-search-cache.end.point}")
private String cacheSearchEndPoint;
@Value("${rest.elatic-cache.end.point}")
private String cacheEndPoint;
public SyncCityCacheResponse syncCityToCityCache(SyncCityCacheRequest syncCityCacheRequest) throws ResourceException {
SyncCityCacheResponse syncCityCacheResponse = null;
try {
logger.info("RestCityService: Hitting CityCacheServiceAPI to push city for request: {}", syncCityCacheRequest.toString());
syncCityCacheResponse = restTemplate.postForObject(new URI(cacheSyncEndPoint), syncCityCacheRequest.getSyncCityDetails(), SyncCityCacheResponse.class);
if (ResourceConstants.FAILURE.equalsIgnoreCase(syncCityCacheResponse.getStatus())) {
throw new ResourceException(ResourceErrors.SYNC_API_ERROR.getErrorCode(),
ResourceErrors.SYNC_API_ERROR.getErrorDescription() + " " + syncCityCacheResponse.getSyncCityDetails().get(0).getDescription());
}
} catch (RestClientException | URISyntaxException e) {
logger.error("RestCityService : Exception while hitting cache to push city, Exception:{}", e);
throw new ResourceException(ResourceErrors.SYNC_API_ERROR.getErrorCode(),
ResourceErrors.SYNC_API_ERROR.getErrorDescription() + " " + syncCityCacheResponse.getSyncCityDetails().get(0).getDescription());
}
return syncCityCacheResponse;
}
@Transactional(rollbackFor= Exception.class) public CityServiceResponse saveCity(CityServiceRequest request, String status){ try { // your logic int i = 1/0; } catch(Exception e) { throw new Exception("Exception occured while saving "); } }
– Kathirvel Subramanian
1 hour ago
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
i hope you are creating ArithmeticException and in method Signature you are throwing ResourceException. you can use try(with resources) and in catch block throw the Exception for Rollback
– Kathirvel Subramanian
1 hour ago