I have a service method that performs the following operations in sequence:
Calls a read method annotated with a custom read-only transaction annotation (equivalent to
@Transactional(readOnly = true))Then calls a write method annotated with a custom annotation that should create a new transaction (equivalent to
@Transactional(propagation = Propagation.REQUIRES_NEW))
I'm getting this error:
[ERROR: cannot execute UPDATE in a read-only transaction]
Exemple: thanks @Robert
// Service class with transactional methods
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// Read-only transaction
@Transactional(readOnly = true)
public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
// Write transaction with REQUIRES_NEW
@Transactional(propagation = Propagation.REQUIRES_NEW)
public User updateUser(User user) {
return userRepository.save(user);
}
}
// Orchestrator service
@Service
public class UserOrchestrationService {
@Autowired
private UserService userService;
@Autowired
private NotificationService notificationService;
// No transaction annotation on this method
public void processUserUpdate(Long userId, String newEmail) {
// Step 1: Read user with READ-ONLY transaction
User existingUser = userService.findUserById(userId);
if (existingUser == null) {
throw new RuntimeException("User not found");
}
// Step 2: Modify user data
existingUser.setEmail(newEmail);
existingUser.setLastModified(new Date());
// Step 3: Save with REQUIRES_NEW transaction - FAILS HERE!
User updatedUser = userService.updateUser(existingUser);
// Step 4: Send notification
notificationService.sendUpdateNotification(updatedUser);
}
}