成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

SpringBoot 實(shí)戰(zhàn) (十) | 聲明式事務(wù)

ygyooo / 1975人閱讀

摘要:前言如題,今天介紹的聲明式事務(wù)。提供一個(gè)注解在配置類上來開啟聲明式事務(wù)的支持。而在配置里還開啟了對聲明式事務(wù)的支持,代碼如下所以在中,無須顯式開啟使用注解。源碼下載后語以上為聲明式事務(wù)的教程。

微信公眾號:一個(gè)優(yōu)秀的廢人
如有問題或建議,請后臺留言,我會(huì)盡力解決你的問題。
前言

如題,今天介紹 SpringBoot 的 聲明式事務(wù)。

Spring 的事務(wù)機(jī)制

所有的數(shù)據(jù)訪問技術(shù)都有事務(wù)處理機(jī)制,這些技術(shù)提供了 API 用于開啟事務(wù)、提交事務(wù)來完成數(shù)據(jù)操作,或者在發(fā)生錯(cuò)誤時(shí)回滾數(shù)據(jù)。

而 Spring 的事務(wù)機(jī)制是用統(tǒng)一的機(jī)制來處理不同數(shù)據(jù)訪問技術(shù)的事務(wù)處理,Spring 的事務(wù)機(jī)制提供了一個(gè) PlatformTransactionManager 接口,不同的數(shù)據(jù)訪問技術(shù)的事務(wù)使用不同的接口實(shí)現(xiàn),如下表:

數(shù)據(jù)訪問技術(shù) 實(shí)現(xiàn)
JDBC DataSourceTransactionManager
JPA JPATransactionManager
Hibernate HibernateTransactionManager
JDO JdoTransactionManager
分布式事務(wù) JtaTransactionManager
聲明式事務(wù)

Spring 支持聲明式事務(wù),即使用注解來選擇需要使用事務(wù)的方法,他使用 @Transactional 注解在方法上表明該方法需要事務(wù)支持。被注解的方法在被調(diào)用時(shí),Spring 開啟一個(gè)新的事務(wù),當(dāng)方法無異常運(yùn)行結(jié)束后,Spring 會(huì)提交這個(gè)事務(wù)。如:

@Transactional
public void saveStudent(Student student){
        // 數(shù)據(jù)庫操作
}

注意,@Transactional 注解來自于 org.springframework.transcation.annotation 包,而不是 javax.transaction。

Spring 提供一個(gè) @EnableTranscationManagement 注解在配置類上來開啟聲明式事務(wù)的支持。使用了 @EnableTranscationManagement 后,Spring 容器會(huì)自動(dòng)掃描注解 @Transactional 的方法與類。@EnableTranscationManagement 的使用方式如下:

@Configuration
@EnableTranscationManagement 
public class AppConfig{

}
注解事務(wù)行為

@Transactional 有如下表所示的屬性來定制事務(wù)行為。

屬性 含義
propagation 事務(wù)傳播行為
isolation 事務(wù)隔離級別
readOnly 事務(wù)的讀寫性,boolean型
timeout 超時(shí)時(shí)間,int型,以秒為單位。
rollbackFor 一組異常類,遇到時(shí)回滾。(rollbackFor={SQLException.class})
rollbackForCalssName 一組異常類名,遇到回滾,類型為 string[]
noRollbackFor 一組異常類,遇到不回滾
norollbackForCalssName 一組異常類名,遇到時(shí)不回滾。
類級別使用 @Transactional

@Transactional 不僅可以注解在方法上,還可以注解在類上。注解在類上時(shí)意味著此類的所有 public 方法都是開啟事務(wù)的。如果類級別和方法級別同時(shí)使用了 @Transactional 注解,則使用在類級別的注解會(huì)重載方法級別的注解。

SpringBoot 的事務(wù)支持

自動(dòng)配置的事務(wù)管理器

在使用 JDBC 作為數(shù)據(jù)訪問技術(shù)時(shí),配置定義如下:

@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(DataSource.class)
public PlatformTransactionManager transactionManager(){
    return new DataSourceTransactionManager(this.dataSource)
}

在使用 JPA 作為數(shù)據(jù)訪問技術(shù)時(shí),配置定義如下:

@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager(){
    return new JpaTransactionManager()
}

自動(dòng)開啟注解事務(wù)的支持

SpringBoot 專門用于配置事務(wù)的類為 org.springframework.boot.autoconfigure.transcation.TransactionAutoConfiguration,此配置類依賴于 JpaBaseConfiguration 和 DataSourceTransactionManagerAutoConfiguration。
而在 DataSourceTransactionManagerAutoConfiguration 配置里還開啟了對聲明式事務(wù)的支持,代碼如下:

@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
@Configuration
@EnableTransactionManagement
protected static class TransactionManagementConfiguration{

}

所以在 SpringBoot 中,無須顯式開啟使用 @EnableTransactionManagement 注解。

實(shí)戰(zhàn)

演示如何使用 Transactional 使用異常導(dǎo)致數(shù)據(jù)回滾與使用異常導(dǎo)致數(shù)據(jù)不回滾。

準(zhǔn)備工作:

SpringBoot 2.1.3
JDK 1.8
IDEA

pom.xml 依賴:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.3.RELEASE
         
    
    com.nasus
    transaction
    0.0.1-SNAPSHOT
    transaction
    transaction Demo project for Spring Boot

    
        1.8
    

    
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            mysql
            mysql-connector-java
            runtime
        
        
        
            org.projectlombok
            lombok
            1.16.20
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

代碼注釋很清楚,沒啥好說的。

application.yaml 配置:

spring:
  # u6570u636Eu5E93u76F8u5173
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true
    username: root
    password: 123456
  # jpa u76F8u5173
  jpa:
    hibernate:
      ddl-auto: update   # ddl-auto:u8BBEu4E3A create u8868u793Au6BCFu6B21u90FDu91CDu65B0u5EFAu8868
    show-sql: true

實(shí)體類:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    private Integer age;
}

dao 層

import com.nasus.transaction.domain.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends JpaRepository {
}

service 層

import com.nasus.transaction.domain.Student;

public interface StudentService {

    Student saveStudentWithRollBack(Student student);

    Student saveStudentWithoutRollBack(Student student);

}

實(shí)現(xiàn)類:

import com.nasus.transaction.domain.Student;
import com.nasus.transaction.repository.StudentRepository;
import com.nasus.transaction.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    // 直接注入 StudentRepository 的 bean
    private StudentRepository studentRepository;

    // 使用 @Transactional 注解的 rollbackFor 屬性,指定特定異常時(shí),觸發(fā)回滾
    @Transactional(rollbackFor = {IllegalArgumentException.class})
    @Override
    public Student saveStudentWithRollBack(Student student) {
        Student s = studentRepository.save(student);
        if ("高斯林".equals(s.getName())){
            //硬編碼,手動(dòng)觸發(fā)異常
            throw new IllegalArgumentException("高斯林已存在,數(shù)據(jù)將回滾");
        }
        return s;
    }

    // 使用 @Transactional 注解的 noRollbackFor 屬性,指定特定異常時(shí),不觸發(fā)回滾
    @Transactional(noRollbackFor = {IllegalArgumentException.class})
    @Override
    public Student saveStudentWithoutRollBack(Student student) {
        Student s = studentRepository.save(student);
        if ("高斯林".equals(s.getName())){
            throw new IllegalArgumentException("高斯林已存在,數(shù)據(jù)將不會(huì)回滾");
        }
        return s;
    }

}

代碼注釋同樣很清楚,沒啥好說的。

controller 層

import com.nasus.transaction.domain.Student;
import com.nasus.transaction.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/student")
public class StudentController {

    // 注入 studentservice 的 bean
    @Autowired
    private StudentService studentService;

    // 測試回滾情況
    @PostMapping("/withRollBack")
    public Student saveStudentWithRollBack(@RequestBody Student student){
        return studentService.saveStudentWithRollBack(student);
    }

    // 測試不回滾情況
    @PostMapping("/withOutRollBack")
    public Student saveStudentWithoutRollBack(@RequestBody Student student){
        return studentService.saveStudentWithoutRollBack(student);
    }
}
Postman 測試結(jié)果

為了更清楚地理解回滾,以 debug (調(diào)試模式) 啟動(dòng)程序。并在 StudentServiceImpl 的 saveStudentWithRollBack 方法上打上斷點(diǎn)。

測試前數(shù)據(jù)庫結(jié)果:

Postman 測試回滾


debug 模式下可見數(shù)據(jù)已保存,且獲得 id 為 1。:

繼續(xù)執(zhí)行拋出異常 IllegalArgumentException,將導(dǎo)致數(shù)據(jù)回滾:

測試后數(shù)據(jù)庫結(jié)果:并無新增數(shù)據(jù),回滾成功。

Postman 測試不回滾

測試前數(shù)據(jù)庫結(jié)果:

遇到 IllegalArgumentException 異常數(shù)據(jù)不會(huì)回滾:

測試后數(shù)據(jù)庫結(jié)果:新增數(shù)據(jù),數(shù)據(jù)不回滾。

源碼下載

https://github.com/turoDog/Demo/tree/master/springboot_transaction_demo

后語

以上為 SpringBoot 聲明式事務(wù)的教程。最后,對 Python 、Java 感興趣請長按二維碼關(guān)注一波,我會(huì)努力帶給你們價(jià)值,如果覺得本文對你哪怕有一丁點(diǎn)幫助,請幫忙點(diǎn)好看,讓更多人知道。

另外,關(guān)注之后在發(fā)送 1024 可領(lǐng)取免費(fèi)學(xué)習(xí)資料。資料內(nèi)容詳情請看這篇舊文:Python、C++、Java、Linux、Go、前端、算法資料分享

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73359.html

相關(guān)文章

  • SpringBoot非官方教程 | 第七篇:SpringBoot開啟聲明事務(wù)

    摘要:準(zhǔn)備階段以上一篇文章的代碼為例子,即整合,上一篇文章是基于注解來實(shí)現(xiàn)的數(shù)據(jù)訪問層,這篇文章基于的來實(shí)現(xiàn),并開啟聲明式事務(wù)。創(chuàng)建實(shí)體類數(shù)據(jù)訪問層接口層用戶減塊用戶加塊,聲明事務(wù),并設(shè)計(jì)一個(gè)轉(zhuǎn)賬方法,用戶減塊,用戶加塊。 springboot開啟事務(wù)很簡單,只需要一個(gè)注解@Transactional 就可以了。因?yàn)樵趕pringboot中已經(jīng)默認(rèn)對jpa、jdbc、mybatis開啟了事事...

    tyheist 評論0 收藏0
  • 深刻理解Spring聲明事務(wù)

    摘要:支持聲明式事務(wù),通過注解控制方法是否支持事務(wù)。聲明式事務(wù),基于實(shí)現(xiàn),將具體業(yè)務(wù)和業(yè)務(wù)邏輯解耦。該級別下事務(wù)順序執(zhí)行,阻止上面的缺陷,開銷很大。 問題引入 Spring中事務(wù)傳播有哪幾種,分別是怎樣的? 理解注解事務(wù)的自動(dòng)配置? SpringBoot啟動(dòng)類為什么不需要加@EnableTransactionManagement注解? 聲明式事務(wù)的實(shí)現(xiàn)原理?(待補(bǔ)充) ...

    Cheng_Gang 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<