最近項目中恰好遇到有須要用事物處理這塊,本身也踩了一些坑,網上找了些資料,大多數都有將 @Transactional 註解進行講解,本身也按照他們的進行操做一下,雖然有些確實講到了,可是每一個人實際操做的時候會不同,不免會踩些坑,爲了一樣的錯誤再也不踩第二次,特意寫了次demo。java
當把一切梳理好以後,發現這個demo太簡單了。git
首先,須要引入jpa的包:github
<!-- jpa:將對象映射到關係數據庫 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
建立一個controller類:web
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類:spring
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瀏覽器
下面是控制檯打印的日誌:app
git 地址:https://github.com/DYH2020/springBootDemo.gitdom
參考文章:https://blog.csdn.net/equaker/article/details/81534922 spring-boot