为什么JPA修改查询需要@Transactional注释?

时间:2015-01-26 14:15:39

标签: spring hibernate jpa

鉴于下面的代码,为什么当我从控制器调用PersonService.updateAccountMembership时,我需要在@Transactional查询(@Modifying)上添加AccountRepo.updateMembership注释?调用修改查询的服务调用上没有@Transactional注释(AccountService.updateMembership)?

如果我删除修改查询中的@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 个答案:

答案 0 :(得分:1)

不确定

你在sql中有两种查询。读取查询和写入查询。

数据库可以有多个客户端。如果两个客户同时更新某个人的性别怎么办?最后一个获胜!

这是一个使用两种方法的示例:void buy()void pay()

  1. 客户A读取下一个空发票号0000001
  2. 客户B读取下一个空发票号0000001
  3. 客户A将invoice0000001-payer更改为Max
  4. 客户A商店发票0000001
  5. 客户B将invoice0000001-payer更改为Tom
  6. 客户B存储发票0000001&lt;&lt; ---崩溃!已经在使用!
  7. 问题:马克斯买了它,但汤姆支付了它。

    如果使用事务,则可以将步骤5与步骤6绑定。如果步骤6失败,则回滚步骤5.

    您的数据库全面需要转换。如果没有。

    ,则无法修改数据