2015-01-26 2 views
0

Учитывая приведенный ниже код, почему это происходит, когда я вызываю PersonService.updateAccountMembership с контроллера. Мне нужно указать аннотацию @Transactional на запрос @Modifying (AccountRepo.updateMembership)? Не содержит аннотации @Transactional на вызов службы, который вызывает требуемый модифицирующий запрос (AccountService.updateMembership)?Почему для изменения запроса JPA требуется аннотация @Transactional?

ниже код сломается, если я удалить @Transactional аннотацию на модифицирующего запроса со следующим исключением:

javax.persistence.TransactionRequiredException: Executing an update/delete query 

Услуги:

@Service 
public class PersonService{ 
    @Autowired 
    PersonRepo personRepo; 

    @Autowired 
    AccountService accountService; 

    public Person updateAccountMembership(Person person, int membership){ 
     person = this.save(person); 
     accountService.updateMembership(person, membership); 
    } 

    @Transactional 
    public Person save(Person person){ 
     return personRepo.save(person); 
    } 
} 

учетной записи службы:

@Service 
public class AccountService { 
    @Autowired 
    AccountRepo accountRepo; 

    @Transactional 
    public void updateMembership(Person person, int membership){ 
      accountRepo.updateMembership(person, membership); 
    } 
} 

Репутация счета:

public class AccountRepo extends JpaRepository<Account,Integer> { 
    @Transactional //WHY IS THIS REQUIRED???????? 
    @Modifying 
    @Query("update .........") 
    void updateMembership(@Param("person") Person person, @Param("memb") int membership); 
} 
+1

Это не должно быть необходимым, однако убедитесь, что транзакции для 'AccountService' фактически применяются. Также вызов 'this.save' не является транзакционным, поскольку он никогда не проходит через прокси-сервер, который применяет транзакцию. –

ответ

0

Конечно

У вас есть два вида запросов в SQL. Запросы чтения и записи-запросы.

База данных может иметь несколько клиентов. Что делать, если два клиента одновременно обновляют пол человека? Последний побеждает!

Это пример, используя два метода: void buy() и void pay().

  1. Client Ряд читать дальше пустой счет-фактура 0000001
  2. Client B прочитать следующий пустой номер счета 0000001
  3. Клиент Изменение invoice0000001 плательщиком Максу
  4. Клиент Магазин счета 0000001
  5. Изменение клиента B invoice0000001-плательщик до Тома
  6. Клиент B хранить счет 0000001 < < --- авария! Уже в использовании!

Проблема: Макс купил его, но Том выплатил его.

Если вы используете транзакции, вы можете привязать шаг 5 с шагом 6. Если шаг 6 не прошел, шаг 5 откат.

Ваша база данных по всем направлениям требует трансакций. Вы не можете изменять данные без них.

+1

Я думаю, что вопроситель понимает транзакции, но спрашивает, почему сконфигурированная транзакция не распространяется на уровне сервиса на уровень репозитория в этом случае. –

+0

@AlanHay Исключение, которое он описывает, говорит со мной: он не использует его через уровень сервиса. –

Смежные вопросы