SpringBoot實戰筆記:24_Spring Boot 的事務支援
阿新 • • 發佈:2019-01-25
24_Spring Boot 的事務支援
- 所有的資料訪問技術都有事務處理機制,這些技術提供了API用來開啟事務,提交事務來完成資料操作,或者在發生錯誤的時候回滾資料。
- Spring 的事務機制是用統一的機制來處理不同的資料訪問技術的事務處理。
- Spring 的事務機制提供了一個
PlatformTransactionManager
介面,不同的資料訪問技術的事務使用不同的介面實現。
資料訪問技術 | 實現類 |
---|---|
JDBC | DataSourceTransactionManager |
JPA | JpaTransactionManager |
Hibernate | HibernateTransactionManager |
JDO | JdoTransactionManager |
分散式事務 | JtaTransactionManager |
定義事務管理器的程式碼如下
@Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}
1,宣告式事務
Spring 支援宣告式事務,即使用註解來選擇需要使用事務的方法(切入點),它使用 @Transactional
註解在方法上,宣告該方法需要事務支援,這是一個基於 AOP 的實現操作。
@Transactional
註解是 org.springframework.transaction.annotation
包下的
Spring 提供了一個 @EnableTransactionManager
註解,在配置類上來開啟宣告式事務的支援。會自動掃註解 @Transactional
的方法和類(表示該類中所有public的方法都需要開啟事務的)。
2,Spring Data JPA 的事務支援
Spring Data JPA 對所有的預設方法都開啟了事務支援,且查詢類事務預設啟用 readOnly=true
屬性。
可以檢視 SimpleJpaRepository
類的原始碼
3,Spring Boot 的事務支援:自動配置的事務管理器
- 在使用JDBC作為資料訪問技術的時候,Spring Boot 為我們定義了
PlatformTransactionManager
的實現DataSourceTransactionManager
的Bean; - 在使用JPA作為資料訪問技術的時候,Spring Boot 為我們定義了
PlatformTransactionManager
的實現JpaTransactionManager
的Bean;
4,Spring Boot 的事務支援:自動開啟註解事務的支援
- Spring Boot 專門用於配置事務的類為 :
TransactionAutoConfiguration
,此配置類依賴於JpaBaseConfiguration
和DataSourceTransactionManagerAutoConfiguration
- 在
DataSourceTransactionManagerAutoConfiguration
裡開啟了對宣告式事務的支援 - 所以在 Spring Boot中,無需顯示的開啟使用
@EnableTransactionManager
註解
5,新建Spring Boot 專案:演示使用異常導致事務回滾
- 匯入
web
與jpa
依賴 - 新增
ojdbc6.jar
依賴,在application.properties
檔案中新增配置
6,建立實體類Person
- 屬性:id(主鍵、自增),name,address,age
- 空引數構造方法,set/get方法
- 別忘了在類上註解 :
@Entity
7,建立實體類的Repository介面(DAO)
public interface PersonRepository extends JpaRepository<Person,Long>{
}
8,建立對應的Service 層
package com.zyf.service;
import com.zyf.domain.Person;
/**
* Created by zyf on 2018/3/13.
*/
public interface PersonService {
/**
* 演示回滾
*/
Person savePersonWithRollBack(Person person);
/**
* 演示不會滾
*/
Person savePersonWithoutRollBack(Person person);
}
package com.zyf.service.impl;
import com.zyf.dao.PersonRepository;
import com.zyf.domain.Person;
import com.zyf.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Created by zyf on 2018/3/13.
*/
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
PersonRepository personRepository;
//通過rollbackfor屬性指定:出現該異常則資料回滾
@Transactional(rollbackFor = {IllegalArgumentException.class})
@Override
public Person savePersonWithRollBack(Person person) {
Person p = personRepository.save(person);
if(person.getName().equals("zyf")){
throw new IllegalArgumentException("不好意思不能存,回滾啦");
}
return p;
}
//通過noRollbackFor屬性指定:出現該異常則資料不回滾
@Transactional(noRollbackFor = {IllegalArgumentException.class})
@Override
public Person savePersonWithoutRollBack(Person person) {
Person p = personRepository.save(person);
if(person.getName().equals("zyf")){
throw new IllegalArgumentException("不好意思不能存,回滾啦");
}
return p;
}
}
9,控制器
package com.zyf.controller;
import com.zyf.domain.Person;
import com.zyf.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created by zyf on 2018/3/13.
*/
@Controller
public class PersonController {
@Autowired
PersonService personService;
@RequestMapping("/rollback")
public Person rollback(Person person){
return personService.savePersonWithRollBack(person);
}
@RequestMapping("/norollback")
public Person noRollback(Person person){
return personService.savePersonWithoutRollBack(person);
}
}
10,測試
訪問不回滾
依然存進去了
訪問回滾的話資料庫中是不會插入新資料的