Spring事務基礎

2021-02-21 碼農沉思錄

點擊上方碼農沉思錄,選擇「設為星標」


前言

我猜大概50%的Java程式設計師(別問我怎麼知道的,反正我就是,太失敗了!!!)現在僅僅局限於一個@Transactional註解或者在XML中配置事務相關的東西,然後除了事務級別之外,其他的事務知識可能是空白的。為了更加全面地學習,所以我就匯總一下Spring事務的知識點,有什麼不對或者補充的,大家記得留言告訴我哈。

為什麼要事務

關於事務的由來,我就不舉例子了,很多人第一反應就是去銀行存錢(然而我是用花唄的)的操作了。

事務的四大特性ACID:

原子性(Atomicity)

一致性(Consistency)

隔離性(Isolation)

持久性(Durability)

事務的隔離級別

(1)read uncommited是最低的事務隔離級別,它允許另外一個事務可以看到這個事務未提交的數據。

(2)read commited保證一個事物提交後才能被另外一個事務讀取。另外一個事務不能讀取該事物未提交的數據。

(3)repeatable read這種事務隔離級別可以防止髒讀,不可重複讀。但是可能會出現幻象讀。它除了保證一個事務不能被另外一個事務讀取未提交的數據之外還避免了以下情況產生(不可重複讀)。

(4)serializable這是花費最高代價但最可靠的事務隔離級別。事務被處理為順序執行。除了防止髒讀,不可重複讀之外,還避免了幻象讀

說明:

a.髒讀指當一個事務正字訪問數據,並且對數據進行了修改,而這種數據還沒有提交到資料庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。因為這個數據還沒有提交那麼另外一個事務讀取到的這個數據我們稱之為髒數據。依據髒數據所做的操作肯能是不正確的。

b.不可重複讀指在一個事務內,多次讀同一數據。在這個事務還沒有執行結束,另外一個事務也訪問該同一數據,那麼在第一個事務中的兩次讀取數據之間,由於第二個事務的修改第一個事務兩次讀到的數據可能是不一樣的,這樣就發生了在一個事物內兩次連續讀到的數據是不一樣的,這種情況被稱為是不可重複讀。

c.幻象讀一個事務先後讀取一個範圍的記錄,但兩次讀取的紀錄數不同,我們稱之為幻象讀(兩次執行同一條 select 語句會出現不同的結果,第二次讀會增加一數據行,並沒有說這兩次執行是在同一個事務中)

接口體系

@Transactional註解估計大家都了解,那麼我們先跟蹤一下它的源碼,發現了PlatformTransactionManager這個接口類,具體的接口方法如下:

public interface PlatformTransactionManager()...{

    // 由TransactionDefinition得到TransactionStatus對象

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    // 提交

    void commit(TransactionStatus status) throws TransactionException;

    // 回滾

    void rollback(TransactionStatus status) throws TransactionException;

    }

它就是定義了我們平時操作事務的三大步驟。具體實現由它的子類來實現,也就是如下圖所示的關係:

事務幾種實現方式

(1)編程式事務管理對基於 POJO 的應用來說是唯一選擇。我們需要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理。(學過Java都會的吧,我就不囉嗦這個了。)(2)基於 TransactionProxyFactoryBean的聲明式事務管理(3)基於 @Transactional 的聲明式事務管理(4)基於Aspectj AOP配置事務

1、編程式事務

具體實現如下:

import org.springframework.transaction.PlatformTransactionManager;

import org.springframework.transaction.TransactionStatus;

import org.springframework.transaction.support.DefaultTransactionDefinition;

//1、注入事務管理器對象

@Autowired

private PlatformTransactionManager txManager;

//2、開啟事務

TransactionStatus status = txManager.getTransaction(new DefaultTransactionDefinition());

//3、提交

txManager.commit(status);

4、回滾

txManager.rollback(status);

使用場景:在springboot項目開發中,涉及到調用第三方接口,請求第三方接口成功但返回相關交易失敗的話,需要刪除插入表的某條數據,或更新別表中的表狀態同時記錄日誌等,將第三方請求的實際完成情況返回給前端。

2、TransactionProxyFactoryBean實現事務

配置文件:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans

    xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

                        http://www.springframework.org/schema/context

                        http://www.springframework.org/schema/context/spring-context-3.0.xsd

                        http://www.springframework.org/schema/tx

                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

                        http://www.springframework.org/schema/aop

                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!-- 引用外部文件 db.properties讀取資料庫配置-->

    <context:property-placeholder location="classpath:db.properties"/>

    <!-- schemaLocation後面兩個命名空間是掃描該包必須有的 -->

    <!-- 掃描com.sunline包以及所有子包,為所有加了註解的類創建bean -->

    <context:component-scan base-package="com.sunline">

    </context:component-scan>

    <bean id="dataSource"

        class="org.apache.commons.dbcp.BasicDataSource">

        <property name="driverClassName"

            value="${driverClassName}">

        </property>

        <property name="url"

            value="${url}">

        </property>

        <property name="username" value="${username}"></property>

        <property name="password" value="${password}"></property>

    </bean>

    <bean id="sessionFactory"

        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">

            <ref bean="dataSource" />

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

                <prop key="dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

                <prop key="hibernate.hbm2ddl.auto">true</prop>

                <prop key="hibernate.show_sql">true</prop>

            </props>

        </property>

        <property name="mappingResources">

            <list>

                <value>com/sunline/entity/Account.hbm.xml</value>

            </list>

        </property>

   </bean>

       <!-- 配置Hibernate事務管理器 -->

     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <property name="sessionFactory" ref="sessionFactory" />

    </bean>

       <!-- ==================================2.使用XML配置聲明式的事務管理(原始方式)=============================================== -->

    <!-- 配置業務層的代理 -->

    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

        <!-- 配置目標對象 -->

        <property name="target" ref="accountBizTwo" />

        <!-- 注入事務管理器 -->

        <property name="transactionManager" ref="transactionManager"></property>

        <!-- 注入事務的屬性 -->

        <property name="transactionAttributes">

            <props>

                <!--

                    prop的格式:

                        * PROPAGATION :事務的傳播行為

                        * ISOTATION :事務的隔離級別

                        * readOnly :只讀

                        * -EXCEPTION :發生哪些異常回滾事務

                        * +EXCEPTION :發生哪些異常不回滾事務

                 -->

                <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop>

                <!-- <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> -->

                <!-- <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> -->

            </props>

        </property>

    </bean>

</beans>

這個主要是使用xml配置事務,其實跟現在的@Transactional 的效果一樣。更多詳細的配置可以參考文章:https://blog.csdn.net/linhaiyun_ytdx/article/details/78236418

3、基於 @Transactional 的聲明式事務管理

這個最簡單,就暫時不細講。

4、基於Aspectj AOP配置事務

1)、創建工具類,用於開啟事務,提交事務,會滾事務

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Scope;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import org.springframework.stereotype.Component;

import org.springframework.transaction.TransactionStatus;

import org.springframework.transaction.interceptor.DefaultTransactionAttribute;

//注入spring容器中

@Component

//創建為多例對象,放置多線程安全問題

@Scope("prototype")

public class AopAspectUtil {

    @Autowired

    private DataSourceTransactionManager manager; //注入spring的事務管理器

   //事務攔截器

    private TransactionStatus transaction;

    public TransactionStatus begin() {

        transaction = manager.getTransaction(new DefaultTransactionAttribute());//設置為默認事務隔離級別

       //返回事務攔截器

        return transaction;

    }

    public void commit() {

       // 提交事務

        manager.commit(transaction);

    }

    public void rollback() {

       //回滾事務

        manager.rollback(transaction);

    }

}

2)、定義註解

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})//設置註解使用範圍

@Retention(RetentionPolicy.RUNTIME)//註解不僅被保存到class文件中,jvm加載class文件之後,仍然存在

public @interface MyTransactional {

}

3)、自定義通知

使用注意,在針對事務管理方面,方法中不要去try{}catch(){},使用try,,catch後aop不能獲取到異常信息,會導致出現異常後不能進行回滾,如果確實需要try,,,catch 可以再finally中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();由此段代碼進行事務的回滾

import com.zbin.aop.mytransation.TransactionUtils;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.transaction.interceptor.TransactionAspectSupport;

@Component

@Aspect

public class AopTransaction {

    @Autowired

    private TransactionUtils transactionUtils;

    @Around("execution(* cn.xbmchina.service.UserService.add(..))")

    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        //調用方法之前執行

        System.out.println("開啟事務");

       transactionUtils.begin();

        proceedingJoinPoint.proceed();

        //調用方法之後執行

        System.out.println("提交事務");

        transactionUtils.commit();

    }

    @AfterThrowing("execution(* cn.xbmchina.aop.service.UserService.add(..))")

    public void afterThrowing() {

        System.out.println("異常通知 ");

        //獲取當前事務進行回滾

        //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

        transactionUtils.rollBack();

    }

}

4)、測試

@MyTransactional

public void add() {

    userDao.add("test001", 20);

    int i = 1 / 0;

    System.out.println("-");

    userDao.add("test002", 20);

}

事務傳播行為

事務傳播行為(propagation behavior)指的就是當一個事務方法被另一個事務方法調用時,這個事務方法應該如何進行。

例如:methodA事務方法調用methodB事務方法時,methodB是繼續在調用者methodA的事務中運行呢,還是為自己開啟一個新事務運行,這就是由methodB的事務傳播行為決定的。

看完還是覺得有點懵,那就一個個地為各位簡單介紹一下唄。

1、PROPAGATION_REQUIRED

如果存在一個事務,則支持當前事務。如果沒有事務則開啟一個新的事務。可以把事務想像成一個膠囊,在這個場景下方法B用的是方法A產生的膠囊(事務)。

@Transactional(propagation = Propagation.REQUIRED)

public void methodA() {

 methodB();

// do something

}

@Transactional(propagation = Propagation.REQUIRED)

public void methodB() {

    // do something

}

單獨調用methodB方法時,因為當前上下文不存在事務,所以會開啟一個新的事務。調用methodA方法時,因為當前上下文不存在事務,所以會開啟一個新的事務。當執行到methodB時,methodB發現當前上下文有事務,因此就加入到當前事務中來。

2、PROPAGATION_SUPPORTS

如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行。但是對於事務同步的事務管理器,PROPAGATION_SUPPORTS與不使用事務有少許不同。

@Transactional(propagation = Propagation.REQUIRED)

public void methodA() {

 methodB();

// do something

}

// 事務屬性為SUPPORTS

@Transactional(propagation = Propagation.SUPPORTS)

public void methodB() {

    // do something

}

單純的調用methodB時,methodB方法是非事務的執行的。當調用methdA時,methodB則加入了methodA的事務中,事務地執行。

3、PROPAGATION_MANDATORY

如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。

@Transactional(propagation = Propagation.REQUIRED)

public void methodA() {

 methodB();

// do something

}

// 事務屬性為MANDATORY

@Transactional(propagation = Propagation.MANDATORY)

public void methodB() {

    // do something

}

當單獨調用methodB時,因為當前沒有一個活動的事務,則會拋出異常throw new IllegalTransactionStateException(「Transaction propagation 『mandatory』 but no existing transaction found」);當調用methodA時,methodB則加入到methodA的事務中,事務地執行。

4、PROPAGATION_MANDATORY

使用PROPAGATION_REQUIRES_NEW,需要使用 JtaTransactionManager作為事務管理器。它會開啟一個新的事務。如果一個事務已經存在,則先將這個存在的事務掛起。

@Transactional(propagation = Propagation.REQUIRED)

public void methodA() {

doSomeThingA();

methodB();

doSomeThingB();

// do something else

}

// 事務屬性為REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRES_NEW)

public void methodB() {

    // do something

}

當調用methodA();時,相當於如下代碼

main(){

    TransactionManager tm = null;

    try{

        //獲得一個JTA事務管理器

        tm = getTransactionManager();

        tm.begin();//開啟一個新的事務

        Transaction ts1 = tm.getTransaction();

        doSomeThing();

        tm.suspend();//掛起當前事務

        try{

            tm.begin();//重新開啟第二個事務

            Transaction ts2 = tm.getTransaction();

            methodB();

            ts2.commit();//提交第二個事務

        } Catch(RunTimeException ex) {

            ts2.rollback();//回滾第二個事務

        } finally {

            //釋放資源

        }

        //methodB執行完後,恢復第一個事務

        tm.resume(ts1);

        doSomeThingB();

        ts1.commit();//提交第一個事務

    } catch(RunTimeException ex) {

        ts1.rollback();//回滾第一個事務

    } finally {

        //釋放資源

    }

}

在這裡,我把ts1稱為外層事務,ts2稱為內層事務。從上面的代碼可以看出,ts2與ts1是兩個獨立的事務,互不相干。Ts2是否成功並不依賴於 ts1。如果methodA方法在調用methodB方法後的doSomeThingB方法失敗了,而methodB方法所做的結果依然被提交。而除了 methodB之外的其它代碼導致的結果卻被回滾了

5、PROPAGATION_NOT_SUPPORTED

PROPAGATION_NOT_SUPPORTED 總是非事務地執行,並掛起任何存在的事務。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作為事務管理器。

6、PROPAGATION_NEVER

總是非事務地執行,如果存在一個活動事務,則拋出異常。

7、PROPAGATION_NESTED

示例:

@Transactional(propagation = Propagation.REQUIRED)

methodA(){

  doSomeThingA();

  methodB();

  doSomeThingB();

}

@Transactional(propagation = Propagation.NEWSTED)

methodB(){

  ……

}

如果單獨調用methodB方法,則按REQUIRED屬性執行。如果調用methodA方法,相當於下面的效果:

main(){

    Connection con = null;

    Savepoint savepoint = null;

    try{

        con = getConnection();

        con.setAutoCommit(false);

        doSomeThingA();

        savepoint = con2.setSavepoint();

        try{

            methodB();

        } catch(RuntimeException ex) {

            con.rollback(savepoint);

        } finally {

            //釋放資源

        }

        doSomeThingB();

        con.commit();

    } catch(RuntimeException ex) {

        con.rollback();

    } finally {

        //釋放資源

    }

}

當methodB方法調用之前,調用setSavepoint方法,保存當前的狀態到savepoint。如果methodB方法調用失敗,則恢復到之前保存的狀態。但是需要注意的是,這時的事務並沒有進行提交,如果後續的代碼(doSomeThingB()方法)調用失敗,則回滾包括methodB方法的所有操作。嵌套事務一個非常重要的概念就是內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗並不會引起外層事務的回滾。

特別地:PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區別在於, PROPAGATION_REQUIRES_NEW 完全是一個新的事務, 而 PROPAGATION_NESTED 則是外部事務的子事務, 如果外部事務 commit, 嵌套事務也會被 commit, 這個規則同樣適用於 roll back.

以上都是一個數據源的情況下的事務處理,那你有沒有想過如果多個數據源的情況下,這個事務如何得到保證呢?還請留意下次更新【Spring多數據源事務】

文章不錯的話記得點個在看喲,在看越多的話可以給大家帶來更多福利

相關焦點

  • Spring事務管理
    TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。4.2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起。4.3.
  • Spring的編程式事務和聲明式事務詳解
    tx標籤配置的攔截器:基於tx和aop名字空間的xml配置文件(基於Aspectj AOP配置事務);全註解:基於@Transactional註解;Spring事務特性Spring所有的事務管理策略類都繼承自org.springframework.transaction.PlatformTransactionManager接口,用於執行具體的事務操作。
  • spring之事務回滾技巧
    當遇到這種情況,我們就可以使用Spring的事務解決這個問題。3、實例這裡使用的事務配置如下:<!-- Jpa 事務配置 --><beanid="transactionManager"class="org.springframework.orm.jpa.JpaTransactionManager"><propertyname="entityManagerFactory"ref="entityManagerFactory"
  • 這可能是對 Spring 事務原理講解最透徹的文章了
    特別聲明:@Transactional註解來自org.springframework.transaction.annotation包,而不是javax.transaction。接下來我們通過分析一些嵌套事務的場景,來深入理解spring事務傳播的機制。
  • 教妹學Java:Spring基礎篇
    本篇文章就打算通過我和三妹對話的形式來學一學「Spring 的基礎」。教妹學 Java,沒見過這麼放肆的標題吧?「語不驚人死不休」,沒錯,本篇文章的標題就是這麼酷炫,不然你怎麼會點進來?我有一個漂亮如花的妹妹(見上圖),她叫什麼呢?我想聰明的讀者能猜得出:沉默王三,沒錯,年方三六。
  • Java Web系列:Spring MVC基礎
    1.Web MVC基礎MVC的本質是表現層模式,我們以視圖模型為中心,將視圖和控制器分離出來。就如同分層模式一樣,我們以業務邏輯為中心,把表現層和數據訪問層代碼分離出來是一樣的方法。框架只能在技術層面上給我們幫助,無法在思考和過程上幫助我們,而我們很多人都不喜歡思考和嘗試。
  • Spring的@Transactional註解詳細用法
    API如JTA更簡單的編程式事務管理API與spring數據訪問抽象的完美集成事務管理方式spring支持編程式事務管理和聲明式事務管理兩種方式。聲明式事務最大的優點就是不需要通過編程的方式管理事務,這樣就不需要在業務邏輯代碼中摻雜事務管理的代碼,只需在配置文件中做相關的事務規則聲明(或通過基於@Transactional註解的方式),便可以將事務規則應用到業務邏輯中。顯然聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式。
  • 帶妹學Java:Spring基礎篇
    1)核心技術:依賴注入(DI)、面向切面編程(AOP)、國際化、數據綁定、類型轉換2)測試:TestContext 框架、Spring MVC 測試3)數據訪問:事務、JDBC、對象關係映射(ORM)4)Spring MVC(一個模型 - 視圖 - 控制器「MVC」的 Web 框架)、Spring WebFlux(一個典型非阻塞異步的框架)
  • spring學習總結(一)_Ioc基礎(上)
    閱讀目錄spring概述Ioc基礎使用XML配置方式實現IOC看了他寫的spring系列的博客,寫的不錯。於是本文的內容參考自他的博客,當然都是手打書寫。由於我感覺他寫的博客篇幅過長。我根據我的習慣進行拆分學習。而且他的文章一系列很清楚。也值得我去學習。自己寫博客就零零散散。不是很系統。spring概述spring可以做很多事情,它為企業級開發提供了豐富的功能。
  • Spring事務實現原理
    事務的管理是受限於具體的數據源的(例如,JDBC對應的事務管理器就是DatasourceTransactionManager),因此PlatformTransactionManager只規定了事務的基本操作:創建事務,提交事物和回滾事務。
  • 一文帶你看懂Spring事務!
    一、閱讀本文需要的基礎知識閱讀這篇文章的同學我默認大家都對Spring事務相關知識有一定的了解了。(ps:如果不了解點解具體的文章去閱讀再回到這裡來哦)我們都知道,Spring事務是Spring AOP的最佳實踐之一,所以說AOP入門基礎知識(簡單配置,使用)是需要先知道的。
  • Java Web系列:Spring依賴注入基礎
    Spring的基礎組件如下圖所示:從圖中可以看出,開始的模塊只有從core\beans\aop\context四個組件,後來添加了context-support【1.2】擴展模塊、expression【3.0】擴展模塊和beans-groovy【4.0】擴展模塊。
  • 在實際開發中對數據流的處理,和事務處理中遇到的坑,及解決方案
    ThrowableSpring框架的事務基礎架構代碼,默認地在運行時和unchecked exceptions時,才進行事務回滾,Errors 同樣默認地也進行事務回滾。try{}catch{}了,事務就不回滾了,如果想讓事務回滾必須再往外拋try{}catch{throw Exception}。
  • Java面試題事務是什麼 SpringAOP對事務管理
    spring概念Spring中的spring-tx包包含了Spring對事務管理的支持。我發現如果在Spring環境下,Spring是不能完成@autowied和@Resourece注入的,不知道是什麼原因,我們需要在導入一個包spring-test。如果在Tommcat環境下Spring就能說夠進行註解注入是不是Spring的註解依賴Tommcat下的某些東西或者是Jstl之類的東西呢?或是另一種可能我們執行Java代碼時,Spring容器沒有完成初始化所以不能注入。
  • 那些讓你愛不釋手的 Spring 代碼技巧
    spring事務要如何避坑?spring中的事務功能主要分為:聲明式事務和編程式事務。聲明式事務大多數情況下,我們在開發過程中使用更多的可能是聲明式事務,即使用@Transactional註解定義的事務,因為它用起來更簡單,方便。
  • Spring全家桶、Dubbo、分布式、消息隊列後端必備全套開源項目
    打好基礎《Spring Boot 快速入門》《Spring Boot 自動配置原理》 對應 lab-47《Spring Boot 芋道 Spring Boot Jar 啟動原理》>《Spring Cloud Alibaba 配置中心 Nacos 入門》 對應 labx-05-spring-cloud-alibaba-nacos-config《Spring Cloud Alibaba 分布式事務 Seata 入門》 對應 labx-17推薦搭配食用
  • Spring Cloud Alibaba 發布 GA 版本,新增 4 個模塊
    版本概要概要: 增加了 4 個新的模塊:spring-cloud-alibaba-dubbo、spring-cloud-alibaba-seata、spring-cloud-alibaba-sentinel-zuul 以及 spring-cloud-alicloud-sms。
  • 寶貝,來,講講 Spring 事務有哪些坑?
    Spring 事務隔離和資料庫事務隔離是不是一個概念5. Spring 事務控制放在 Service 層,在 Service 方法中一個方法調用 Service 中的另一個方法,默認開啟幾個事務引言今天,我們來講 Spring 中和事務有關的考題。
  • spring微服務中的那點事
    Spring通過TransactionManager來實現事務管理,現有兩種方式,一種是通過aop注入式的方式實現,另一種是通過@Transactional在方法上實現事務管理.:A上加了註解,B上不加,則整體會受事務控制.
  • 史上最全spring boot實戰文檔,吃透這些,面試幹掉80%對手
    最大的重要性是:springcloud是一個基於springboot實現的一系 列框架的集合,用來提供全局的服務治理方案。springcloud要基於springboot來實現,離不開springboot。如果要學習源碼,當然還是SpringBoot最適合不過了。