Transaction.java
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.room;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a method in a {@link Dao} class as a transaction method.
* <p>
* When used on a non-abstract method of an abstract {@link 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.
* <p>
* Example:
* <pre>
* {@literal @}Dao
* public abstract class SongDao {
* {@literal @}Insert
* public abstract void insert(Song song);
* {@literal @}Delete
* public abstract void delete(Song song);
* {@literal @}Transaction
* public void insertAndDeleteInTransaction(Song newSong, Song oldSong) {
* // Anything inside this method runs in a single transaction.
* insert(newSong);
* delete(oldSong);
* }
* }
* </pre>
* <p>
* When used on a {@link Query} method that has a {@code 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:
* <ol>
* <li>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
* {@link android.database.CursorWindow CursorWindow}, the query result may be corrupted due to
* changes in the database in between cursor window swaps.
* <li>If the result of the query is a POJO with {@link Relation} fields, these fields are
* queried separately. To receive consistent results between these queries, you also want
* to run them in a single transaction.
* </ol>
* Example:
* <pre>
* class AlbumWithSongs extends Album {
* {@literal @}Relation(parentColumn = "albumId", entityColumn = "songId")
* public List<Song> songs;
* }
*
* {@literal @}Dao
* public interface AlbumDao {
* {@literal @}Transaction {@literal @}Query("SELECT * FROM album")
* public List<AlbumWithSongs> loadAll();
* }
* </pre>
* If the query is asynchronous (e.g. returns a {@link androidx.lifecycle.LiveData LiveData}
* or RxJava {@code Flowable}), the transaction is properly handled when the query is run, not when
* the method is called.
* <p>
* Putting this annotation on an {@link Insert}, {@link Update} or {@link Delete} method has no
* impact because those methods are always run inside a transaction. Similarly, if a method is
* annotated with {@link Query} but runs an INSERT, UPDATE or DELETE statement, it is automatically
* wrapped in a transaction and this annotation has no effect.
* <p>
* Room will only perform at most one transaction at a time, additional transactions are queued
* and executed on a first come, first serve order.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
public @interface Transaction {
}