最近项目中刚好遇到有需要用事物处理这块,自己也踩了一些坑,网上找了些资料,大多数都有将 @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
下面是控制台打印的日志:
git 地址:https://github.com/DYH2020/springBootDemo.git
参考文章:https://blog.csdn.net/equaker/article/details/81534922
https://blog.csdn.net/moshowgame/article/details/80092935