# Transaction

Artifact: [androidx.room3:room3-common](https://developer.android.com/jetpack/androidx/releases/room3) [View Source](https://cs.android.com/search?q=file:androidx/room3/Transaction.kt+class:androidx.room3.Transaction) Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/room3#3.0.0)

*** ** * ** ***

Common/AllAndroid/JVMNative/C/iOSJavaScript
- Cmn

  ```
  @Target(allowedTargets = [AnnotationTarget.FUNCTION])
  @Retention(value = AnnotationRetention.BINARY)
  annotation Transaction
  ```

*** ** * ** ***

Marks a function in a `https://developer.android.com/reference/kotlin/androidx/room3/Dao` class as a transaction function.

When used on a non-abstract function of an abstract `https://developer.android.com/reference/kotlin/androidx/room3/Dao` class, the derived implementation of the function will execute the super function in a database transaction. All the parameters and return types are preserved. The transaction will be marked as successful unless an exception is thrown in the function body.

Example:

```kotlin
@Dao
abstract class SongDao {
    @Insert
    abstract suspend fun insert(song: Song)

    @Delete
    abstract suspend fun delete(song: Song)

    @Transaction
    suspend fun insertAndDeleteInTransaction(newSong: Song, oldSong: Song) {
        // Anything inside this function runs in a single transaction.
        insert(newSong)
        delete(oldSong)
    }
}
```

When used on a `https://developer.android.com/reference/kotlin/androidx/room3/Query` function that has a `SELECT` statement, the generated code for the `https://developer.android.com/reference/kotlin/androidx/room3/Query` will be run in a transaction. There are 2 main cases where you may want to do that:

- If the result of the query is a data object class with `https://developer.android.com/reference/kotlin/androidx/room3/Relation` properties, these properties are queried separately. To receive consistent results between these queries, you also want to run them in a single transaction.

- If the result of the query is fairly big such that it creates implications with the `https://developer.android.com/reference/kotlin/androidx/sqlite/SQLiteDriver` implementation provided to Room. Specifically for a driver that uses Android's SQLite binding it is better to run a query with a large result inside a transaction to receive a consistent results. Otherwise, if the query result does not fit into a single android.database.CursorWindow, the query result may be corrupted due to changes in the database in between cursor window swaps.

Example:

```kotlin
data class AlbumWithSongs(
    val album: Album
    @Relation(parentColumn = "albumId", entityColumn = "songId")
    val songs: List<Song>
)

@Dao
interface AlbumDao {
    @Transaction
    @Query("SELECT * FROM album")
    suspend fun loadAll(): List<AlbumWithSongs>
}
```

If the query is asynchronous (e.g. returns a `https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html`), the transaction is properly handled when the query is run, not when the function is called.

Putting this annotation on an `https://developer.android.com/reference/kotlin/androidx/room3/Insert`, `https://developer.android.com/reference/kotlin/androidx/room3/Update` or `https://developer.android.com/reference/kotlin/androidx/room3/Delete` function has no impact because those functions are always run inside a transaction. Similarly, if a function is annotated with `https://developer.android.com/reference/kotlin/androidx/room3/Query` but executes an `INSERT`, `UPDATE` or `DELETE` statement, it is automatically wrapped in a transaction and this annotation has no effect. For write statement Room will only perform at most one transaction at a time, additional transactions are queued and executed on a first come, first served order.

## Summary

| ### Public constructors |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/room3/Transaction#Transaction()()` | Cmn |

## Public constructors

### Transaction

Cmn

```
Transaction()
```