zoukankan      html  css  js  c++  java
  • spring boot jpa update 操作

    有好多文章介绍了spring boot 博客已经很多了比如说: 
    http://blog.csdn.net/linzhiqiang0316/article/details/52639265 
    http://blog.csdn.net/linzhiqiang0316/article/details/52638039 
    http://blog.didispace.com/springbootmultidatasource/等等 
    上面几个博客都是有关查询的一些例子,但是今天我们收的是jpa删除和事务的一些坑 
    使用的spring boot版本:1.3.7.RELEASE

    一.业务场景(在线考试系统)和代码:

    业务逻辑:根据问题的id删除答案

    repository层:

      int deleteByQuestionId(Integer questionId);
    • 1
    • 1

    service 层:

    public void deleteChoiceAnswerByQuestionId(Integer questionId) {
        choiceAnswerRepository.deleteByQuestionId(questionId);
    • 1
    • 2
    • 1
    • 2

    test(测试)层:

       @Test
        public void testDeleteByQuestionId() {
    
            choiceAnswerService.deleteChoiceAnswerByQuestionId(5);
            System.out.println("hehehhe");
            System.out.println("hehehhe");
    
            System.out.println("hehehhe");
    
            System.out.println("hehehhe");
            System.out.println("hehehhe");
            System.out.println("hehehhe");
            System.out.println("hehehhe");
    
    
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二.问题

    问题1:对于modify和move时如果各层都不加事务管理的话会报这个错误

    org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call 
    • 1
    • 1

    当我们除了query外的modiy和delete如果各层的方法中没有进行事务管理的话(没加@Transactional)话会报错

    问题2:只在test层加@Transactional

    没有错误但是数据并没有被删除,在用IDEA的调试是,在执行这个测试方法的过程时还可以在choiceanswer表中进行操作并没有加锁事务并没有起作用

    问题3:只在 Repository层加@Transactional

     public void deleteChoiceAnswerByQuestionId(Integer questionId) {
            choiceAnswerRepository.deleteByQuestionId(questionId);
            System.out.println("hehehhe");
    
            System.out.println("hehehhe");
    //        questionRepository.delete(5);
            System.out.println("hehehhe");
    
            System.out.println("hehehhe");
            System.out.println("hehehhe");
            System.out.println("hehehhe");
            System.out.println("hehehhe");
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这时当执行完 
    choiceAnswerRepository.deleteByQuestionId(questionId); 
    数据里面被修改,修改成功

    问题4:只在 service层加@Transactional

    当只有执行完service内的对应方法时数据才会被删除(只有在这一层加事务管理才是真正的事务管理)

    问题5:在service 层和repository层都加上@transactional

    当只有执行完service内的对应方法时数据才会被删除

    问题6:只有在test层加上@Transactional,不管service层和repository层加不加@Transactional(可以加可以不加)

    数据都不会被删除

    问题7:repository层不同注解的执行结果

    @Modifying
    @Query("delete from ChoiceAnswer c where c.question.id=?1 ")
    @Transactional
    int deleteByQuestionId(Integer questionId);
    与
    @Transactional
    int deleteByQuestionId(Integer questionId);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    有什么区别,上面的会直接执行delete语句 
    下面的会先执行select 再执行delete

    总结:

    事务管理只有在service加上事务管理才起作用,query不需要事务管理但是delete update modify都需要事务管理。为了不在service层不加事务管理可以在repository层的delete update modify加上@transactional 但这样不能真正保持事务的完整性

  • 相关阅读:
    洛谷P2062 分队问题
    bzoj1800 飞行棋
    UVA11100 The Trip, 2007
    UVA11134 Fabled Rooks
    每天一道博弈论之“威佐夫博弈”
    每天一道博弈论之“A game”(伪博弈
    每天一道博弈论之“谁能赢呢?”
    每天一道博弈论之“牛的数字游戏”
    每天一道博弈论之“E&D”
    每天一道博弈论之“巴什博弈”
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106802.html
Copyright © 2011-2022 走看看