事务性

默认情况下,继承自 SimpleJpaRepository 的方法继承事务配置。 对于读取操作,事务配置标志设置为 。 所有其他都配置了 plain,以便应用默认事务配置。 由事务性存储库片段支持的存储库方法从实际片段方法继承事务性属性。CrudRepositoryreadOnlytrue@Transactionalspring-doc.cn

如果需要调整存储库中声明的方法之一的事务配置,请在存储库接口中重新声明该方法,如下所示:spring-doc.cn

示例 1.CRUD 的自定义交易配置
public interface UserRepository extends CrudRepository<User, Long> {

  @Override
  @Transactional(timeout = 10)
  public List<User> findAll();

  // Further query method declarations
}

这样做会导致方法以 10 秒的超时运行,并且没有标志。findAll()readOnlyspring-doc.cn

改变事务行为的另一种方法是使用(通常)覆盖多个存储库的 Facade 或服务实现。其目的是定义非 CRUD 操作的事务边界。以下示例显示了如何对多个存储库使用此类 Facade:spring-doc.cn

示例 2.使用 Facade 定义多个存储库调用的事务
@Service
public class UserManagementImpl implements UserManagement {

  private final UserRepository userRepository;
  private final RoleRepository roleRepository;

  public UserManagementImpl(UserRepository userRepository,
    RoleRepository roleRepository) {
    this.userRepository = userRepository;
    this.roleRepository = roleRepository;
  }

  @Transactional
  public void addRoleToAllUsers(String roleName) {

    Role role = roleRepository.findByName(roleName);

    for (User user : userRepository.findAll()) {
      user.addRole(role);
      userRepository.save(user);
    }
  }
}

此示例导致 call to 在事务内运行(参与现有事务,如果没有运行,则创建新事务)。然后,存储库中的事务配置将被忽略,因为外部事务配置决定了实际使用的事务配置。请注意,您必须 activate 或 explicitly use 才能使基于 Comments 的 Facade 配置正常工作。 此示例假定您使用组件扫描。addRoleToAllUsers(…)<tx:annotation-driven />@EnableTransactionManagementspring-doc.cn

请注意,从 JPA 的角度来看,对 的调用并不是绝对必要的,但为了与 Spring Data 提供的存储库抽象保持一致,它仍然应该存在。savespring-doc.cn

事务查询方法

默认情况下,声明的查询方法(包括默认方法)不会应用任何事务配置。 要以事务方式运行这些方法,请在您定义的存储库接口中使用,如以下示例所示:@Transactionalspring-doc.cn

例 3.在 Query 方法中使用 @Transactional
@Transactional(readOnly = true)
interface UserRepository extends JpaRepository<User, Long> {

  List<User> findByLastname(String lastname);

  @Modifying
  @Transactional
  @Query("delete from User u where u.active = false")
  void deleteInactiveUsers();
}

通常,您希望将标志设置为 ,因为大多数查询方法仅读取数据。与此相反,使用 Comments 并覆盖事务配置。因此,该方法在运行时将标志设置为 。readOnlytruedeleteInactiveUsers()@ModifyingreadOnlyfalsespring-doc.cn

您可以将事务用于只读查询,并通过设置标志将其标记为只读查询。但是,这样做并不能检查您不会触发操纵查询(尽管某些数据库在只读事务中拒绝 and 语句)。相反,该标志作为提示传播到底层 JDBC 驱动程序,以实现性能优化。此外,Spring 在底层 JPA 提供程序上执行一些优化。例如,当与 Hibernate 一起使用时,flush 模式被设置为当你将事务配置为 时,这会导致 Hibernate 跳过脏检查(对大型对象树的显着改进)。readOnlyINSERTUPDATEreadOnlyNEVERreadOnlyspring-doc.cn