使用@Transactional(readOnly = true)有什么优势?

Lex*_*int 4 spring hibernate transactions spring-transactions spring-data

我是新手,据我所知,@Transactional只需确保@Transactional将带有注释的类或方法的所有内部工作都包装在一个事务中,并且来自外部源的所有调用将创建一个新事务,但是为什么我们实际上需要这些注释?下面的存储库以及readOnly = true在常见情况下使用它的优势是什么?这是使用SpringHibernatehttps://github.com/spring-projects/spring-petclinic)的Spring pet-clinic示例应用程序。

/**
 * Repository class for <code>Pet</code> domain objects All method names are compliant with Spring Data naming
 * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation
 *
 * @author Ken Krebs
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @author Michael Isvy
 */
public interface PetRepository extends Repository<Pet, Integer> {

    /**
     * Retrieve all {@link PetType}s from the data store.
     * @return a Collection of {@link PetType}s.
     */
    @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
    @Transactional(readOnly = true)
    List<PetType> findPetTypes();

    /**
     * Retrieve a {@link Pet} from the data store by id.
     * @param id the id to search for
     * @return the {@link Pet} if found
     */
    @Transactional(readOnly = true)
    Pet findById(Integer id);

    /**
     * Save a {@link Pet} to the data store, either inserting or updating it.
     * @param pet the {@link Pet} to save
     */
    void save(Pet pet);

}
Run Code Online (Sandbox Code Playgroud)

Cep*_*pr0 7

根据Spring Data作者Oliver Gierke 的解释

Reading methods like findAll() and findOne(…) are using @Transactional(readOnly = true) which is not strictly necessary but triggers a few optimizations in the transaction infrastructure (setting the FlushMode to MANUAL to let persistence providers potentially skip dirty checks when closing the EntityManager). Beyond that the flag is set on the JDBC Connection as well which causes further optimizations on that level.

Depending on what database you use it can omit table locks or even reject write operations you might trigger accidentally. Thus we recommend using @Transactional(readOnly = true) for query methods as well which you can easily achieve adding that annotation to you repository interface. Make sure you add a plain @Transactional to the manipulating methods you might have declared or re-decorated in that interface.