事务控制

使用Spring Data JPA的JpaRepository或者其实现时,数据持久层对原生方法默认已经开启了事务,无需人工干预。

原生方法是指JpaRepository中已经提供的方法。

本文中的“事务”均指本地事务。考虑到性能等问题,不使用分布式事务。

数据持久层

在自己实现的数据持久层中,对于JpaRepository中未提供的方法,默认采用只读事务。因此,对于修改数据的方法,需要配置@Transactional注解,开启非只读事务。

FooRepository.java
package com.example.demo.repository;

import com.example.demo.entity.Foo;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.repository.query.Param;

import javax.transaction.Transactional;
import java.util.List;

public interface FooRepository extends JpaRepository<Foo, Long>, JpaSpecificationExecutor<Foo> {

    List<Foo> findByName(String name);

    @Transactional
    @Query("update Foo set name = :name where id = : id")
    void updateName(@Param("id") Long id, @Param("name") String name);
}

业务逻辑层

在业务逻辑层中,有时候需要组合多种资源完成特定的操作。此时,为保证数据一致性,通常需要在业务逻辑层增加事务控制。

CompositeService.java
package com.example.demo.service;

import com.example.demo.repository.BarRepository;
import com.example.demo.repository.FooRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@Service
public class CompositeService {
    @Autowired
    private FooRepository fooRepository;
    @Autowired
    private BarRepository barRepository;

    @Transactional
    public void compositeMethod() {
        fooRepository.doSomething();
        barRepository.doSomething();
    }
}

仅当所有资源均为本地资源时,本地事务才起作用。分布式环境下,建议采用事件驱动的方式实现最终一致性。

Last updated