トランザクション性
デフォルトでは、CrudRepository
から継承されたメソッドは SimpleJpaRepository
(Javadoc) からトランザクション構成を継承します。読み取り操作の場合、トランザクション構成 readOnly
フラグが true
に設定されます。他のすべてはプレーンな @Transactional
で構成されているため、デフォルトのトランザクション構成が適用されます。トランザクションリポジトリフラグメントによってサポートされるリポジトリメソッドは、実際のフラグメントメソッドからトランザクション属性を継承します。
リポジトリで宣言されているメソッドの 1 つのトランザクション構成を微調整する必要がある場合は、次のように、リポジトリインターフェースでメソッドを再宣言します。
public interface UserRepository extends CrudRepository<User, Long> {
@Override
@Transactional(timeout = 10)
public List<User> findAll();
// Further query method declarations
}
これを行うと、findAll()
メソッドは 10 秒のタイムアウトで、readOnly
フラグなしで実行されます。
トランザクションの動作を変更するもう 1 つの方法は、(通常)複数のリポジトリをカバーするファサードまたはサービス実装を使用することです。その目的は、非 CRUD 操作のトランザクション境界を定義することです。次の例は、そのようなファサードを複数のリポジトリに使用する方法を示しています。
@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
を明示的に使用する必要があることに注意してください。この例では、コンポーネントスキャンを使用することを前提としています。
JPA の観点からは save
の呼び出しは厳密には必要ありませんが、Spring Data によって提供されるリポジトリの抽象化との整合性を保つために必要です。
トランザクションクエリメソッド
宣言されたクエリメソッド (既定のメソッドを含む) は、既定で適用されるトランザクション構成を取得しません。これらのメソッドをトランザクションで実行するには、次の例に示すように、定義したリポジトリインターフェースで @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();
}
通常、ほとんどのクエリメソッドはデータの読み取りのみを行うため、readOnly
フラグを true
に設定する必要があります。それとは対照的に、deleteInactiveUsers()
は @Modifying
アノテーションを使用して、トランザクション構成をオーバーライドします。メソッドは readOnly
フラグを false
に設定して実行されます。
|
例ではリポジトリでの |