Lock the provided table to prevent writes but allow reads, uses `(TABLOCK, HOLDLOCK)`. This will set the transaction isolation level to `READ COMMITTED` and then obtain the lock using a `SELECT` statement that will not read any data from the table. The lock is released after transaction commit or rollback.
(
&mut self,
schema: &str,
table: &str,
)
| 423 | /// lock using a `SELECT` statement that will not read any data from the table. |
| 424 | /// The lock is released after transaction commit or rollback. |
| 425 | pub async fn lock_table_shared( |
| 426 | &mut self, |
| 427 | schema: &str, |
| 428 | table: &str, |
| 429 | ) -> Result<(), SqlServerError> { |
| 430 | // Locks in MS SQL server do not behave the same way under all isolation levels. In testing, |
| 431 | // it has been observed that if the isolation level is SNAPSHOT, these locks are ineffective. |
| 432 | static SET_READ_COMMITTED: &str = "SET TRANSACTION ISOLATION LEVEL READ COMMITTED;"; |
| 433 | // This query probably seems odd, but there is no LOCK command in MS SQL. Locks are specified |
| 434 | // in SELECT using the WITH keyword. This query does not need to return any rows to lock the table, |
| 435 | // hence the 1=0, which is something short that always evaluates to false in this universe. |
| 436 | let query = format!( |
| 437 | "{SET_READ_COMMITTED}\nSELECT * FROM {schema}.{table} WITH (TABLOCK, HOLDLOCK) WHERE 1=0;", |
| 438 | schema = quote_identifier(schema), |
| 439 | table = quote_identifier(table) |
| 440 | ); |
| 441 | let _result = self.client.simple_query(query).await?; |
| 442 | Ok(()) |
| 443 | } |
| 444 | |
| 445 | /// See [`Client::execute`]. |
| 446 | pub async fn execute<'q>( |