亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文詳解Spring事務(wù)的實(shí)現(xiàn)與本質(zhì)

 更新時(shí)間:2023年04月04日 08:49:41   作者:歸去來(lái)?兮  
這篇文章主要介紹了Spring中事務(wù)的兩種實(shí)現(xiàn)方式:聲明式事務(wù)、編程式事務(wù)以及他們的本質(zhì)。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、Spring事務(wù)的基礎(chǔ)知識(shí)

先回憶下Spring事務(wù)的基礎(chǔ)知識(shí)事務(wù)的隔離級(jí)別與Spring事務(wù)的傳播機(jī)制。我們知道數(shù)據(jù)庫(kù)層面是不支持事務(wù)的傳播機(jī)制的,這個(gè)是Spring獨(dú)有的

1.臟讀、不可重復(fù)讀、幻讀

臟讀:對(duì)于同一條數(shù)據(jù)在一個(gè)事務(wù)中多次讀取的結(jié)果不一致,原因是第二次讀取數(shù)據(jù)時(shí)讀取的數(shù)據(jù)被其他未提交的事務(wù)修改了,當(dāng)隔離級(jí)別是讀未提交時(shí)就會(huì)有這種問(wèn)題存在。

不可重復(fù)讀:對(duì)于同一條數(shù)據(jù)在一個(gè)事務(wù)中多次讀取的結(jié)果不一致,原因是第二次讀取數(shù)據(jù)時(shí)讀取的數(shù)據(jù)被其他已提交的事務(wù)修改了,當(dāng)隔離級(jí)別是讀已提交時(shí)就會(huì)有這種問(wèn)題存在。

幻讀:臟讀和不可重復(fù)讀都是針對(duì)一條數(shù)據(jù)來(lái)說(shuō)的,而我們使用重復(fù)讀的隔離級(jí)別就可以解決臟讀和不可重復(fù)讀的問(wèn)題了,但是還是會(huì)有幻讀的問(wèn)題,那什么是幻讀呢?幻讀指的是范圍查詢前后檢索結(jié)果不一致,比如說(shuō)事務(wù)里第一次查詢customer表有10萬(wàn)記錄,同一個(gè)事務(wù)第二次查詢時(shí)有11萬(wàn)記錄,這就是幻讀?;米x產(chǎn)生的原因不是事務(wù)并發(fā)修改導(dǎo)致的(不可),而是查詢時(shí)有其他事務(wù)在做插入,導(dǎo)致了數(shù)據(jù)在量上出現(xiàn)了變化。

2.事務(wù)的隔離級(jí)別

Spring支持的事務(wù)隔離級(jí)別與數(shù)據(jù)的隔離級(jí)別其實(shí)沒(méi)有任何區(qū)別都是四種,說(shuō)隔離級(jí)別必須要說(shuō)事務(wù)的四大特性原子性、一致性、隔離性、持久性。需要拿出來(lái)說(shuō)的便是隔離性,事務(wù)在支持隔離性時(shí)并不是將事務(wù)之間直接徹底隔離,而是給我們提供了幾個(gè)級(jí)別來(lái)劃分隔離的程度,也就是下面四種了。只有串行化才可以做到事務(wù)之間的完全隔離,而其他的隔離級(jí)別自然就會(huì)產(chǎn)生不同的問(wèn)題了,因?yàn)槭聞?wù)之間有交叉。

  • 讀未提交:這是最低的隔離級(jí)別,相當(dāng)于事務(wù)之間的隔離性基本沒(méi)有,所以這種隔離級(jí)別什么問(wèn)題都解決不了,使用這種隔離級(jí)別會(huì)伴隨臟讀、不可重復(fù)讀、幻讀等問(wèn)題。
  • 讀已提交:同一個(gè)事務(wù)里讀取的數(shù)據(jù)是其他事務(wù)里已經(jīng)提交的數(shù)據(jù),所以不會(huì)讀取到其他事務(wù)未提交的數(shù)據(jù),所有不會(huì)有臟讀的問(wèn)題,但是還是可能發(fā)生不可重復(fù)讀、幻讀的問(wèn)題。
  • 重復(fù)讀:同一個(gè)事務(wù)里支持重復(fù)讀取,也就是同一個(gè)事務(wù)里前后讀取的某條數(shù)據(jù)肯定一致(只針對(duì)某一條數(shù)據(jù)而言),但是仍然解決不了幻讀的問(wèn)題,幻讀是因?yàn)椴l(fā)插入導(dǎo)致的。重復(fù)讀只能解決并發(fā)修改的問(wèn)題。
  • 串行化:串行化可以解決隔離性產(chǎn)生的所有問(wèn)題,但是他的效率特別的低,所有任務(wù)都會(huì)排隊(duì)進(jìn)行處理,在并發(fā)系統(tǒng)中效率非常低下。

3.事務(wù)的傳播機(jī)制

事務(wù)的傳播機(jī)制是Spring特有的機(jī)制,各個(gè)數(shù)據(jù)庫(kù)是不支持的,那Spring的傳播機(jī)制是什么呢,他們有什么作用呢?

  • PROPAGATION_REQUIRED(默認(rèn)):如果當(dāng)前方法沒(méi)有事務(wù),就創(chuàng)建一個(gè)新事務(wù);如果當(dāng)前方法已經(jīng)有事務(wù),就加入到當(dāng)前事務(wù)中。
  • PROPAGATION_SUPPORTS:如果當(dāng)前方法有事務(wù),就加入到當(dāng)前事務(wù)中;如果當(dāng)前方法沒(méi)有事務(wù),就以非事務(wù)的方式執(zhí)行。
  • PROPAGATION_MANDATORY:如果當(dāng)前方法有事務(wù),就加入到當(dāng)前事務(wù)中;如果當(dāng)前方法沒(méi)有事務(wù),就拋出異常。
  • PROPAGATION_REQUIRES_NEW:無(wú)論當(dāng)前方法是否有事務(wù),都創(chuàng)建一個(gè)新事務(wù);如果當(dāng)前方法已經(jīng)有事務(wù),就掛起當(dāng)前事務(wù)。
  • PROPAGATION_NOT_SUPPORTED:以非事務(wù)的方式執(zhí)行當(dāng)前方法;如果當(dāng)前方法有事務(wù),就掛起當(dāng)前事務(wù)。
  • PROPAGATION_NEVER:以非事務(wù)的方式執(zhí)行當(dāng)前方法;如果當(dāng)前方法有事務(wù),就拋出異常。
  • PROPAGATION_NESTED:在當(dāng)前事務(wù)中創(chuàng)建一個(gè)嵌套事務(wù);如果當(dāng)前方法沒(méi)有事務(wù),就相當(dāng)于PROPAGATION_REQUIRED。

二、Spring事務(wù)的實(shí)現(xiàn)方式

Spring提供了兩種事務(wù)的支持方式一種常用的聲明式事務(wù),所謂聲明式事務(wù)就是我們直接使用注解聲明即可,而無(wú)需手動(dòng)寫(xiě)事務(wù)的開(kāi)啟提交和回滾,這種事務(wù)的實(shí)現(xiàn)方式是AOP,AOP底層則是JDK的動(dòng)態(tài)代理和CGLIB的動(dòng)態(tài)代理。另一種支持的事務(wù)則是編程式事務(wù),這種實(shí)現(xiàn)方式則是直接編寫(xiě)事務(wù)代碼,底層通過(guò)ORM框架調(diào)用到數(shù)據(jù)庫(kù)實(shí)現(xiàn)的事務(wù),編程式事務(wù)具有更加靈活的特點(diǎn),同時(shí)Spring為我們提供了兩種編程式事務(wù)的實(shí)現(xiàn)方式,一種是TransactionTemplate,一種是PlatformTransactionManager。他們都能實(shí)現(xiàn)編程式事務(wù),不過(guò)使用TransactionTemplate無(wú)需我們手動(dòng)提交或者回滾,Spring會(huì)根據(jù)異常拋出與否進(jìn)行提交或者回滾。使用PlatformTransactionManager就需要我們自己提交或者回滾了。下面看下他們的實(shí)現(xiàn)區(qū)別吧

1.編程式事務(wù)

使用TransactionTemplate實(shí)現(xiàn)編程式事務(wù)

下面是使用TransactionTemplate的偽代碼,我們可以為T(mén)ransactionTemplate指明他的隔離級(jí)別和傳播機(jī)制,注意這里并沒(méi)有配置數(shù)據(jù)源相關(guān)操作,數(shù)據(jù)源仍需要單獨(dú)在配置文件中進(jìn)行聲明數(shù)據(jù)源的類型和驅(qū)動(dòng)類以及其他的數(shù)據(jù)庫(kù)訪問(wèn)的賬號(hào)路徑超時(shí)時(shí)間最大連接等信息。

@Component
public class TestTransactionTemplate {

    
    private TransactionTemplate transactionTemplate;
    
	@Inject
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    }

    public void transferMoney(final String fromAccount, final String toAccount, final double amount) {
        transactionTemplate.execute(new TransactionCallback<Void>() {
            public Void doInTransaction(TransactionStatus status) {
                try {
                    // 執(zhí)行轉(zhuǎn)賬操作,將金額從fromAccount轉(zhuǎn)到toAccount
//                    accountService.transfer(fromAccount, toAccount, amount);
                    // 如果沒(méi)有發(fā)生異常,則提交事務(wù)
                    return null;
                } catch (Exception ex) {
                    // 如果發(fā)生異常,則回滾事務(wù)
                    status.setRollbackOnly();
                    throw new RuntimeException(ex);
                }
            }
        });
    }
}

使用PlatformTransactionManager實(shí)現(xiàn)

使用PlatformTransactionManager則必須我們手動(dòng)進(jìn)行提交或者回滾,下面是他的偽代碼

@Component
public class TestPlatformTransactionManager {

    PlatformTransactionManager transactionManager;

    @Inject
    public void setTransactionManager(PlatformTransactionManager transactionManager){
        this.transactionManager = transactionManager;
    }

    public void transfer(String fromAccount, String toAccount, double amount) {
        DefaultTransactionDefinition txDef = new DefaultTransactionDefinition();
        txDef.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
        txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
        try {
            //執(zhí)行轉(zhuǎn)賬操作,將金額從fromAccount轉(zhuǎn)到toAccount
//            accountService.transfer(fromAccount, toAccount, amount);
            //如果沒(méi)有發(fā)生異常,則提交事務(wù)
            transactionManager.commit(txStatus);
        } catch (Exception ex) {
            //如果發(fā)生異常,則回滾事務(wù)
            transactionManager.rollback(txStatus);
            throw ex;
        }
    }
}

2.聲明式事務(wù)

聲明式事務(wù)底層利用AOP的方式對(duì)我們的事務(wù)對(duì)象進(jìn)行代理,然后通過(guò)前后的增強(qiáng)操作實(shí)現(xiàn)了事務(wù)的管理,其實(shí)底層他們還是一樣的,使用聲明式事務(wù)的偽代碼如下,我們可以為注解聲明需要的各種屬性,常用的就是事務(wù)的傳播機(jī)制、隔離級(jí)別、超時(shí)時(shí)間、回滾異常、非回滾異常等。

@Component
public class TestTransactional {

    @Transactional(propagation = Propagation.REQUIRES_NEW //設(shè)置傳播機(jī)制
            ,isolation = Isolation.REPEATABLE_READ //設(shè)置隔離級(jí)別
            ,readOnly = false //設(shè)置是否只讀
            ,timeout = 30 //設(shè)置數(shù)據(jù)庫(kù)連接的超時(shí)時(shí)間
            ,transactionManager = "defaultTransactionManager" //設(shè)置事務(wù)管理器,一個(gè)工程多個(gè)時(shí)可以使用該方式
            ,rollbackFor = IllegalArgumentException.class // 指定回滾異常
            ,noRollbackFor = IndexOutOfBoundsException.class) // 指定非回滾異常
    public Boolean transfer(String fromAccount, String toAccount, double amount){

        // 業(yè)務(wù)操作...

        return Boolean.TRUE;
    }
}

三、Spring事務(wù)的本質(zhì)

Spring雖然提供了多種事務(wù)的實(shí)現(xiàn)方式,其實(shí)最底層都是有一樣的。他都必須依賴數(shù)據(jù)源來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn),根據(jù)數(shù)據(jù)源來(lái)進(jìn)行不同的封裝就實(shí)現(xiàn)了Spring的不同的事務(wù)實(shí)現(xiàn)方式。編程式事務(wù)是直接獲取數(shù)據(jù)源后進(jìn)行手動(dòng)操作,我們使用的PlatformTransactionManager、或者TransactionTemplate都是需要利用數(shù)據(jù)源來(lái)進(jìn)行操作的。Spring通過(guò)數(shù)據(jù)源來(lái)和數(shù)據(jù)庫(kù)建立連接,開(kāi)啟連接后我們就可以為這個(gè)連接設(shè)置他的隔離級(jí)別和一些超時(shí)信息等。這樣就會(huì)建立起一個(gè)事務(wù)了,最底層利用的還是數(shù)據(jù)庫(kù)的事務(wù)的動(dòng)作。聲明式事務(wù)與編程式事務(wù)原理都是一致,只不過(guò)Spring通過(guò)AOP將我們的業(yè)務(wù)代碼進(jìn)行了代理,產(chǎn)生了一個(gè)代理對(duì)象,具體使用什么代理技術(shù)Spring會(huì)根據(jù)我們的實(shí)現(xiàn)類進(jìn)行選擇使用JDK還是CGLIB。產(chǎn)生的代理對(duì)象我們就可以在被Transactional注解修飾的方法的前后添加事務(wù)處理的相關(guān)代碼了,這個(gè)代碼和使用編程式事務(wù)的代碼區(qū)別不大。所以說(shuō)Spring事務(wù)的本質(zhì)其實(shí)還是利用數(shù)據(jù)源打開(kāi)和數(shù)據(jù)庫(kù)的連接,在連接上進(jìn)行事務(wù)的操作。Spring根據(jù)不同需要又封裝了不同的事務(wù)實(shí)現(xiàn),底層卻都是一致的。

四、Spring中事務(wù)常碰到的問(wèn)題

這里總結(jié)兩個(gè)常見(jiàn)的事務(wù)問(wèn)題事務(wù)的回滾和不回滾,以及事務(wù)嵌套的場(chǎng)景

1.事務(wù)回滾

在不聲明回滾異常類時(shí),只要被事務(wù)管理的方法發(fā)生異常,那么事務(wù)就是會(huì)回滾的。Spring根據(jù)拋出的異常來(lái)進(jìn)行事務(wù)回滾。如果我們對(duì)異常進(jìn)行了cath那Spring是無(wú)法進(jìn)行事務(wù)回滾的,因?yàn)闆](méi)有異常拋出了。如果想要回滾我們可以手動(dòng)聲明一個(gè)自定義異?;蛘咧付ǖ钠渌惓?。這樣就可以實(shí)現(xiàn)回滾。當(dāng)然即使拋出了異常也不一定會(huì)回滾。這個(gè)還需要依賴我們指定的異?;貪L類,一般可以為T(mén)ransactional指明noRollBackFor。通過(guò)他可以指明在哪些異常下不回滾。通過(guò)rollBackFor指明哪些異常下回滾,需要滿足回滾異常時(shí)才會(huì)去回滾。

那如果把異常catch了,又沒(méi)有拋出異常我們有沒(méi)有其他方式進(jìn)行回滾呢(使用聲明式事務(wù)時(shí))?其實(shí)還有一種方式進(jìn)行回滾,如下所示:

@Transactional
public void someMethod() {
    
    if (condition) {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
}

這種操作就是拿到當(dāng)前事務(wù)的狀態(tài)手動(dòng)更改為回滾狀態(tài),當(dāng)執(zhí)行到AOP的后置增強(qiáng)時(shí),就會(huì)調(diào)用回滾方法,從而達(dá)到了回滾的目的。

2.事務(wù)嵌套

有沒(méi)有思考過(guò)這個(gè)問(wèn)題:Spring的事務(wù)的傳播機(jī)制到底是做什么用的呢?

其實(shí)一般場(chǎng)景下Spring的事務(wù)傳播機(jī)制很少用得到,我們通常都是不顯示指定傳播機(jī)制的,而是使用默認(rèn)的PROPAGATION_REQUIRED。默認(rèn)的這個(gè)傳播機(jī)制就是有事務(wù)那我就使用你的事務(wù),如果沒(méi)有事務(wù)我就新建一個(gè)事務(wù)。假如有以下的場(chǎng)景存在,為了方便看就是用a、b命名方法了:

    @Transactional
    public void a(){ 
        //a方法被事務(wù)管理了,同時(shí)又調(diào)用了b這個(gè)事務(wù)方法
        b();
    }
    
    @Transactional
    public void b(){

???????    }

在此時(shí)我們不為a、b兩個(gè)方法聲明傳播機(jī)制時(shí),那a、b兩個(gè)方法其實(shí)是共用一個(gè)事務(wù)的,因?yàn)樗麄兊氖聞?wù)傳播機(jī)制是PROPAGATION_REQUIRED。這個(gè)機(jī)制就是有事務(wù)就用已經(jīng)存在的,沒(méi)有則新建,很顯然a方法時(shí)開(kāi)啟了一個(gè)事務(wù),執(zhí)行b方法時(shí)既然事務(wù)以及存在,就使用了a的事務(wù)。所以a、b方法其實(shí)是共用事務(wù)的?;乜吹谝徊糠諷pring中事務(wù)的傳播機(jī)制其實(shí)有7種,其實(shí)這其中主要就是為了事務(wù)嵌套場(chǎng)景下使用的,也就是我們事務(wù)中又調(diào)用了事務(wù)的場(chǎng)景。此時(shí)我們就需要關(guān)注內(nèi)層事務(wù)到底需要做什么,需不需要和上層事務(wù)保持一致的動(dòng)作,如果不需要我們就可以選擇PROPAGATION_REQUIRED_NEW,這樣內(nèi)層事務(wù)就是一個(gè)全新的事務(wù)。此時(shí)Spring是通過(guò)數(shù)據(jù)源和數(shù)據(jù)庫(kù)新建立了一個(gè)連接,從而實(shí)現(xiàn)了新的事務(wù)開(kāi)啟。

此外在其中傳播機(jī)制中最后一種需要單獨(dú)說(shuō)下:PROPAGATION_NESTED,他是嵌套事務(wù)。這個(gè)才是真正為嵌套事務(wù)使用的傳播機(jī)制。上面的例子中有內(nèi)層事務(wù)和外層事務(wù)其實(shí)他的原理還是不同的事務(wù)。而PROPAGATION_NESTED嵌套事務(wù)的底層卻是使用的一個(gè)事務(wù)實(shí)現(xiàn)的嵌套事務(wù)。此時(shí)上面的代碼可以改造如下:

    @Transactional(propagation = Propagation.REQUIRED)
    public void a(){
        //a方法被事務(wù)管理了,同時(shí)又調(diào)用了b這個(gè)事務(wù)方法
        b();
    }

    @Transactional(propagation = Propagation.NESTED)
    public void b(){

    }

此時(shí)b方法就是一個(gè)嵌套事務(wù)了,Spring的嵌套事務(wù)同樣底層是依賴于數(shù)據(jù)庫(kù)的嵌套事務(wù),在Mysql里支持了一種偽嵌套事務(wù),就是通過(guò)在一個(gè)事務(wù)中保存回滾點(diǎn)savepoint的方式來(lái)進(jìn)行事務(wù)嵌套。當(dāng)事務(wù)正常提交時(shí)都會(huì)提交,當(dāng)事務(wù)異常時(shí)我們可以指定事務(wù)回滾到指定的回滾點(diǎn),下面列舉一個(gè)Mysql的回滾例子:假設(shè)有一個(gè)員工表employees表,對(duì)他進(jìn)行了如下的操作:

START TRANSACTION;
SAVEPOINT sp1;

INSERT INTO employees (id, name, age) VALUES (1, 'Alice', 30);

SAVEPOINT sp2;

INSERT INTO employees (id, name, age) VALUES (3, 'Bob', 25);

SAVEPOINT sp3;

INSERT INTO employees (id, name, age) VALUES (4, 'Charlie', 27);

SAVEPOINT sp4;

INSERT INTO employees (id, name, age) VALUES (5, 'Dave', 29);

ROLLBACK TO sp3;
COMMIT;

上面的例子我們創(chuàng)建了4個(gè)回滾點(diǎn),且我們最后是回滾到了sp3這個(gè)savepoint,那就意味著sp3之后的所有操作不會(huì)被寫(xiě)入數(shù)據(jù)庫(kù),而sp3之前的所有操作還是會(huì)正常入庫(kù),這樣就實(shí)現(xiàn)了事務(wù)嵌套場(chǎng)景下的部分回滾機(jī)制。Spring事務(wù)傳播機(jī)制中的PROPAGATION_NESTED底層正是利用了Mysql的這一功能進(jìn)行了事務(wù)嵌套場(chǎng)景下的部分回滾。

五、總結(jié)

這篇先介紹了事務(wù)的基礎(chǔ)知識(shí),然后總結(jié)了Spring事務(wù)的支持方式,分析了他們的原理,最后總結(jié)下來(lái)就會(huì)發(fā)現(xiàn)Spring的事務(wù)其實(shí)全部都是依賴于數(shù)據(jù)源對(duì)數(shù)據(jù)庫(kù)的事務(wù)操作,若是數(shù)據(jù)庫(kù)事務(wù)不支持的動(dòng)作,Spring也是不支持的。Spring事務(wù)的支持動(dòng)作都是依賴于底層數(shù)據(jù)庫(kù)事務(wù)的封裝,包括了嵌套事務(wù)的場(chǎng)景,希望這一篇的總結(jié)可以幫助到路過(guò)的朋友。

到此這篇關(guān)于一文詳解Spring事務(wù)的實(shí)現(xiàn)與本質(zhì)的文章就介紹到這了,更多相關(guān)Spring事務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Intellij IDEA的Facets和Artifacts

    詳解Intellij IDEA的Facets和Artifacts

    這篇文章主要介紹了Intellij IDEA的Facets和Artifacts的相關(guān)知識(shí),本文通過(guò)實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-09-09
  • java網(wǎng)上圖書(shū)商城(8)訂單模塊3

    java網(wǎng)上圖書(shū)商城(8)訂單模塊3

    這篇文章主要為大家詳細(xì)介紹了java網(wǎng)上圖書(shū)商城,訂單模塊第三篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • java 簡(jiǎn)單的計(jì)算器程序?qū)嵗a

    java 簡(jiǎn)單的計(jì)算器程序?qū)嵗a

    這篇文章主要介紹了java 簡(jiǎn)單的計(jì)算器程序?qū)嵗a的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java 創(chuàng)建PDF打印小冊(cè)子案例

    Java 創(chuàng)建PDF打印小冊(cè)子案例

    這篇文章主要給大家分享Java 創(chuàng)建PDF打印小冊(cè)子案例,PDF打印小冊(cè)子是指將PDF格式文檔在打印成刊物前需要提前進(jìn)行的頁(yè)面排版,以便在打印后裝訂成冊(cè),下面文章內(nèi)容我們將下面以Java代碼展示如何來(lái)實(shí)現(xiàn),需要的朋友可以參考一下
    2021-10-10
  • java基礎(chǔ)二叉搜索樹(shù)圖文詳解

    java基礎(chǔ)二叉搜索樹(shù)圖文詳解

    二叉樹(shù)是一種非常重要的數(shù)據(jù)結(jié)構(gòu),它同時(shí)具有數(shù)組和鏈表各自的特點(diǎn),下面這篇文章主要給大家介紹了關(guān)于java基礎(chǔ)二叉搜索樹(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Java中四種線程池的使用示例詳解

    Java中四種線程池的使用示例詳解

    這篇文章主要給大家介紹了關(guān)于Java中四種線程池的使用方法,四種線程池分別包括FixedThreadPool、CachedThreadPool、ScheduledThreadPool以及SingleThreadExecutor,文中給出了詳細(xì)的示例代碼供大家參考,需要的朋友們下面來(lái)一起看看吧。
    2017-08-08
  • Java內(nèi)存模型知識(shí)詳解

    Java內(nèi)存模型知識(shí)詳解

    這篇文章主要介紹了Java內(nèi)存模型知識(shí)詳解,文中通過(guò)對(duì)內(nèi)存訪問(wèn)時(shí)的交互關(guān)系圖解介紹的十分詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐

    從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐

    這篇文章主要為大家介紹了從繁瑣到簡(jiǎn)潔的Jenkins?Pipeline腳本優(yōu)化實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 詳解如何在spring boot中使用spring security防止CSRF攻擊

    詳解如何在spring boot中使用spring security防止CSRF攻擊

    這篇文章主要介紹了詳解如何在spring boot中使用spring security防止CSRF攻擊,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 使用CI/CD工具Github Action發(fā)布jar到Maven中央倉(cāng)庫(kù)的詳細(xì)介紹

    使用CI/CD工具Github Action發(fā)布jar到Maven中央倉(cāng)庫(kù)的詳細(xì)介紹

    今天通過(guò)對(duì)Github Action的簡(jiǎn)單使用來(lái)介紹了CI/CD的作用,這個(gè)技術(shù)體系是項(xiàng)目集成交付的趨勢(shì),也是面試中的一個(gè)亮點(diǎn)技能。 而且這種方式可以實(shí)現(xiàn)“一次配置,隨時(shí)隨地集成部署”,感興趣的朋友一起看看吧
    2021-07-07

最新評(píng)論