mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-03 09:51:11 -05:00
Adding @nested_transactional for transactions that require more than one
db update/insert. Using a savepoint for the multiple transactions allows us to rollback if there is an error when executing the second db transaction. However, this does add a bit of complexity. Developers need to manage the db session when calling multiple nested tranactions. Unit tests have been added to test this functionality and some end to end tests have been done to make sure all transactions are rollback if there is an exception while executing the transaction.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
from flask import Blueprint, abort, current_app, jsonify, request
|
||||
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
||||
|
||||
from app import db
|
||||
from app.config import QueueNames
|
||||
from app.dao.annual_billing_dao import set_default_free_allowance_for_service
|
||||
from app.dao.fact_billing_dao import fetch_usage_year_for_organisation
|
||||
@@ -119,17 +120,13 @@ def link_service_to_organisation(organisation_id):
|
||||
service = dao_fetch_service_by_id(data['service_id'])
|
||||
service.organisation = None
|
||||
|
||||
dao_add_service_to_organisation(service, organisation_id)
|
||||
# Need to do the annual billing update in a separate transaction because the both the
|
||||
# dao_add_service_to_organisation and set_default_free_allowance_for_service are wrapped in a transaction.
|
||||
# Catch and report an error if the annual billing doesn't happen - but don't rollback the service update.
|
||||
try:
|
||||
dao_add_service_to_organisation(service, organisation_id)
|
||||
set_default_free_allowance_for_service(service, year_start=None)
|
||||
except SQLAlchemyError:
|
||||
# No need to worry about key errors because service.organisation_type has a foreign key to organisation_types
|
||||
current_app.logger.exception(
|
||||
f"Exception caught when trying to update annual billing when the organisation "
|
||||
f"changed for service: {service.id} to organisation: {organisation_id}")
|
||||
db.session.commit()
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
raise e
|
||||
|
||||
return '', 204
|
||||
|
||||
|
||||
Reference in New Issue
Block a user