此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data JPA 3.4.0! |
事务性
默认情况下,从CrudRepository
从 inherit the transactional configuration fromSimpleJpaRepository
.
对于读取作,事务配置readOnly
flag 设置为true
.
所有其他 API 都配置了 plain@Transactional
,以便应用默认事务配置。
由事务性存储库片段支持的存储库方法从实际片段方法继承事务性属性。
如果需要调整存储库中声明的方法之一的事务配置,请在存储库接口中重新声明该方法,如下所示:
public interface UserRepository extends CrudRepository<User, Long> {
@Override
@Transactional(timeout = 10)
public List<User> findAll();
// Further query method declarations
}
这样做会导致findAll()
方法以 10 秒的超时运行,并且没有readOnly
旗。
改变事务行为的另一种方法是使用(通常)覆盖多个存储库的 Facade 或服务实现。其目的是定义非 CRUD作的事务边界。以下示例显示了如何对多个存储库使用此类 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);
}
}
}
此示例导致对addRoleToAllUsers(…)
在事务内运行(参与现有事务,如果没有正在运行,则创建一个新事务)。然后,存储库中的事务配置将被忽略,因为外部事务配置决定了实际使用的事务配置。请注意,您必须激活<tx:annotation-driven />
或使用@EnableTransactionManagement
explicitly 地让基于 Comments 的 Facade 配置工作。
此示例假定您使用组件扫描。
请注意,对save
从 JPA 的角度来看,并不是绝对必要的,但为了与 Spring Data 提供的存储库抽象保持一致,它仍然应该存在。
事务查询方法
默认情况下,声明的查询方法(包括默认方法)不会应用任何事务配置。
要以事务方式运行这些方法,请使用@Transactional
在您定义的 repository 界面中,如以下示例所示:
@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();
}
通常,您希望readOnly
标志设置为true
,因为大多数查询方法只读取数据。与此相反,deleteInactiveUsers()
利用@Modifying
注解并覆盖事务配置。因此,该方法使用readOnly
flag 设置为false
.
您可以将事务用于只读查询,并通过设置 |