From 5bea3c94c197382ceab1ed7fc8dccb6783364843 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Wed, 18 Dec 2024 20:36:38 +0000 Subject: [PATCH] Add write transactions --- backend/sync_server/src/database.rs | 18 ++++++++++++++++-- .../sync_server/src/server/create_document.rs | 2 +- .../sync_server/src/server/delete_document.rs | 2 +- .../sync_server/src/server/update_document.rs | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/backend/sync_server/src/database.rs b/backend/sync_server/src/database.rs index 0241651a..fb1ec1c5 100644 --- a/backend/sync_server/src/database.rs +++ b/backend/sync_server/src/database.rs @@ -1,4 +1,4 @@ -use std::str::FromStr; +use std::{str::FromStr, time::Duration}; use anyhow::{Context, Result}; use models::{ @@ -21,6 +21,7 @@ impl Database { pub async fn try_new(config: &DatabaseConfig) -> Result { let connection_options = SqliteConnectOptions::from_str(&config.sqlite_url)? .create_if_missing(true) + .busy_timeout(Duration::from_secs(3600)) .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal); let pool = SqlitePoolOptions::new() @@ -49,13 +50,26 @@ impl Database { .context("Cannot check for pending migrations") } - pub async fn create_transaction(&self) -> Result> { + /// Attempting to write from this transaction might result in a + /// database locked error. Use this transaction for read-only operations. + pub async fn create_readonly_transaction(&self) -> Result> { self.connection_pool .begin() .await .context("Cannot create transaction") } + pub async fn create_write_transaction(&self) -> Result> { + let mut transaction = self.create_readonly_transaction().await?; + + // sqlx doesn't support immediate transactions for sqlite: https://github.com/launchbadge/sqlx/issues/481 + sqlx::query!("END; BEGIN IMMEDIATE;") + .execute(&mut *transaction) + .await?; + + Ok(transaction) + } + /// Return the latest state of all non-deleted documents in the vault pub async fn get_latest_documents( &self, diff --git a/backend/sync_server/src/server/create_document.rs b/backend/sync_server/src/server/create_document.rs index 796443fa..0e1bf8b1 100644 --- a/backend/sync_server/src/server/create_document.rs +++ b/backend/sync_server/src/server/create_document.rs @@ -38,7 +38,7 @@ pub async fn create_document( let mut transaction = state .database - .create_transaction() + .create_write_transaction() .await .map_err(server_error)?; diff --git a/backend/sync_server/src/server/delete_document.rs b/backend/sync_server/src/server/delete_document.rs index a966a546..40b87bb2 100644 --- a/backend/sync_server/src/server/delete_document.rs +++ b/backend/sync_server/src/server/delete_document.rs @@ -38,7 +38,7 @@ pub async fn delete_document( let mut transaction = state .database - .create_transaction() + .create_write_transaction() .await .map_err(server_error)?; diff --git a/backend/sync_server/src/server/update_document.rs b/backend/sync_server/src/server/update_document.rs index 08d9ac93..0648017c 100644 --- a/backend/sync_server/src/server/update_document.rs +++ b/backend/sync_server/src/server/update_document.rs @@ -54,7 +54,7 @@ pub async fn update_document( let mut transaction = state .database - .create_transaction() + .create_write_transaction() .await .map_err(server_error)?;