sprinboot jpa下事物回滚demo

时间:2022-09-11 13:37:32

  最近项目中刚好遇到有需要用事物处理这块,自己也踩了一些坑,网上找了些资料,大多数都有将 @Transactional 注解进行讲解,自己也按照他们的进行操作一下,虽然有些确实讲到了,但是每个人实际操作的时候会不一样,难免会踩些坑,为了同样的错误不再踩第二次,特地写了次demo。

  当把一切梳理好之后,发现这个demo太简单了。

  首先,需要引入jpa的包:

<!-- jpa:将对象映射到关系数据库 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

  

  创建一个controller类:

package com.test.demo.controllers;

import com.test.demo.domain.entities.Address;
import com.test.demo.services.TransactionalService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController("/transaction")
@RequestMapping({"/transaction"})
public class TransactionalController {

    private static final Logger logger = LoggerFactory.getLogger(TransactionalController.class);

    @Autowired
    private TransactionalService transactionalService;

    /**
     * @return
     */
    @RequestMapping(value = "/updateTest")
    public String demo() {
        Address address = null;
        try {
            address = transactionalService.findById(4);
            System.out.println("修改之前:" + address.getAddress());
            address = transactionalService.updateName(4, "这里是修改之后的数据");
            System.out.println("修改之后:" + address.getAddress());
        } catch (Exception e) {
            logger.error(e.getMessage());
            Address localAddress = transactionalService.findById(4);
            System.out.println("再次去数据库查找:" + localAddress.getAddress());
        }
        return "";
    }
}

  

  相应的service类:

package com.test.demo.services;

import com.test.demo.domain.entities.Address;
import com.test.demo.domain.entities.AddressRepository;
import com.test.demo.utils.Checker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 事物相关测试业务
 */
@Service
public class TransactionalService {

    @Autowired
    private AddressRepository addressRepository;


    /**
     * 根据ID找到对象
     *
     * @param id
     * @return
     */
    public Address findById(int id) {
        return addressRepository.findOne(id);
    }

    /**
     * 修改地区名称
     *
     * @param id
     * @param address
     * @return
     */
    @Transactional
    public Address updateName(int id, String address) {
        Address a = addressRepository.findOne(id);
        if (!Checker.isNone(a)) {
            a.setAddress(address);
            addressRepository.save(a);
            System.out.println("修改之后:" + a.getAddress());
            if (true) {
                throw new RuntimeException("这里抛出异常啦");
            }
            return a;
        }
        return null;
    }

}

 

  注:如果是在service里面封装了多个方法,那一定要在controller类引用service的那个方法上加 @Transactional ,如果在service下做try catch处理或者没有直接在controller类直接引用service类里面的那个方法上加 @Transactional 注解,那么就没法进行回滚,本人就是在这里踩坑踩了好久(哭死~)

  从git中拉取demo,启动代码之后,在浏览器里面输入:http://127.0.0.1:8025/transaction/updateTest

  下面是控制台打印的日志:

  sprinboot jpa下事物回滚demo

  

  git 地址:https://github.com/DYH2020/springBootDemo.git

 

  参考文章:https://blog.csdn.net/equaker/article/details/81534922 

       https://blog.csdn.net/moshowgame/article/details/80092935