最近项目中刚好遇到有需要用事物处理这块,自己也踩了一些坑,网上找了些资料,大多数都有将 @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