Use a SQL transaction.

This commit is contained in:
LukeMathWalker 2021-03-13 10:08:54 +00:00
parent b21e9cc99c
commit c58675a5a0

View file

@ -5,7 +5,7 @@ use actix_web::{web, HttpResponse};
use chrono::Utc;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use sqlx::PgPool;
use sqlx::{PgPool, Transaction, Postgres};
use std::convert::TryInto;
use uuid::Uuid;
@ -43,14 +43,16 @@ pub async fn subscribe(
.0
.try_into()
.map_err(|_| HttpResponse::BadRequest().finish())?;
let subscriber_id = insert_subscriber(&pool, &new_subscriber)
let mut transaction = pool.begin().await.map_err(|_| HttpResponse::InternalServerError().finish())?;
let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber)
.await
.map_err(|_| HttpResponse::InternalServerError().finish())?;
// We are swallowing the error for the time being.
let subscription_token = generate_subscription_token();
store_token(&pool, subscriber_id, &subscription_token)
store_token(&mut transaction, subscriber_id, &subscription_token)
.await
.map_err(|_| HttpResponse::InternalServerError().finish())?;
transaction.commit().await.map_err(|_| HttpResponse::InternalServerError().finish())?;
let _ = send_confirmation_email(
&email_client,
new_subscriber,
@ -98,10 +100,10 @@ pub async fn send_confirmation_email(
#[tracing::instrument(
name = "Saving new subscriber details in the database",
skip(new_subscriber, pool)
skip(new_subscriber, transaction)
)]
pub async fn insert_subscriber(
pool: &PgPool,
transaction: &mut Transaction<'_, Postgres>,
new_subscriber: &NewSubscriber,
) -> Result<Uuid, sqlx::Error> {
let subscriber_id = Uuid::new_v4();
@ -115,7 +117,7 @@ pub async fn insert_subscriber(
new_subscriber.name.as_ref(),
Utc::now()
)
.execute(pool)
.execute(transaction)
.await
.map_err(|e| {
tracing::error!("Failed to execute query: {:?}", e);
@ -126,10 +128,10 @@ pub async fn insert_subscriber(
#[tracing::instrument(
name = "Store subscription token in the database",
skip(subscription_token, pool)
skip(subscription_token, transaction)
)]
pub async fn store_token(
pool: &PgPool,
transaction: &mut Transaction<'_, Postgres>,
subscriber_id: Uuid,
subscription_token: &str,
) -> Result<(), sqlx::Error> {
@ -141,7 +143,7 @@ pub async fn store_token(
subscription_token,
subscriber_id
)
.execute(pool)
.execute(transaction)
.await
.map_err(|e| {
tracing::error!("Failed to execute query: {:?}", e);