Transaction
@Target([AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER]) class Transaction
androidx.room.Transaction |
Marks a method in a Dao
class as a transaction method.
When used on a non-abstract method of an abstract Dao
class, the derived implementation of the method will execute the super method 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 method body.
Example:
@Dao
public abstract class SongDao {
@Insert
public abstract void insert(Song song);
@Delete
public abstract void delete(Song song);
@Transaction
public void insertAndDeleteInTransaction(Song newSong, Song oldSong) {
// Anything inside this method runs in a single transaction.
insert(newSong);
delete(oldSong);
}
}
When used on a Query
method that has a SELECT
statement, the generated code for the 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 fairly big, it is better to run it inside a transaction to receive a consistent result. Otherwise, if the query result does not fit into a single
CursorWindow
, the query result may be corrupted due to changes in the database in between cursor window swaps. - If the result of the query is a POJO with
Relation
fields, these fields are queried separately. To receive consistent results between these queries, you also want to run them in a single transaction.
class AlbumWithSongs extends Album {
@Relation(parentColumn = "albumId", entityColumn = "songId")
public List<Song> songs;
}
@Dao
public interface AlbumDao {
@Transaction @Query("SELECT * FROM album")
public List<AlbumWithSongs> loadAll();
}
If the query is asynchronous (e.g. returns a LiveData
or RxJava Flowable
), the transaction is properly handled when the query is run, not when the method is called.
Putting this annotation on an Insert
, Update
or Delete
method has no impact because those methods are always run inside a transaction. Similarly, if a method is annotated with Query
but runs an INSERT, UPDATE or DELETE statement, it is automatically wrapped in a transaction and this annotation has no effect.
Room will only perform at most one transaction at a time, additional transactions are queued and executed on a first come, first serve order.
Summary
Public constructors |
|
---|---|
<init>() Marks a method in a |
Public constructors
<init>
Transaction()
Marks a method in a Dao
class as a transaction method.
When used on a non-abstract method of an abstract Dao
class, the derived implementation of the method will execute the super method 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 method body.
Example:
@Dao
public abstract class SongDao {
@Insert
public abstract void insert(Song song);
@Delete
public abstract void delete(Song song);
@Transaction
public void insertAndDeleteInTransaction(Song newSong, Song oldSong) {
// Anything inside this method runs in a single transaction.
insert(newSong);
delete(oldSong);
}
}
When used on a Query
method that has a SELECT
statement, the generated code for the 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 fairly big, it is better to run it inside a transaction to receive a consistent result. Otherwise, if the query result does not fit into a single
CursorWindow
, the query result may be corrupted due to changes in the database in between cursor window swaps. - If the result of the query is a POJO with
Relation
fields, these fields are queried separately. To receive consistent results between these queries, you also want to run them in a single transaction.
class AlbumWithSongs extends Album {
@Relation(parentColumn = "albumId", entityColumn = "songId")
public List<Song> songs;
}
@Dao
public interface AlbumDao {
@Transaction @Query("SELECT * FROM album")
public List<AlbumWithSongs> loadAll();
}
If the query is asynchronous (e.g. returns a LiveData
or RxJava Flowable
), the transaction is properly handled when the query is run, not when the method is called.
Putting this annotation on an Insert
, Update
or Delete
method has no impact because those methods are always run inside a transaction. Similarly, if a method is annotated with Query
but runs an INSERT, UPDATE or DELETE statement, it is automatically wrapped in a transaction and this annotation has no effect.
Room will only perform at most one transaction at a time, additional transactions are queued and executed on a first come, first serve order.