欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring事務(wù)管理零基礎(chǔ)入門(mén)

 更新時(shí)間:2022年10月03日 11:07:58   作者:Dily_Su  
事務(wù)的作用就是為了保證用戶的每一個(gè)操作都是可靠的,事務(wù)中的每一步操作都必須成功執(zhí)行,只要有發(fā)生異常就?回退到事務(wù)開(kāi)始未進(jìn)行操作的狀態(tài)。事務(wù)管理是Spring框架中最為常用的功能之一,我們?cè)谑褂肧pring?Boot開(kāi)發(fā)應(yīng)用時(shí),大部分情況下也都需要使用事務(wù)

一、簡(jiǎn)介

概念:事務(wù)是數(shù)據(jù)庫(kù)操作的最小工作單元,是作為單個(gè)邏輯工作單元執(zhí)行的一系列操作,這些操作一起提交,要么都執(zhí)行,要么都不執(zhí)行。事務(wù)時(shí)一組不可分割的操作集合(工作邏輯單元)。

簡(jiǎn)而言之,就是一系列操作要么都執(zhí)行成功(事務(wù)提交),要么都執(zhí)行失?。ㄊ聞?wù)回滾)

二、特性(一原持久隔離)

2.1 原子性

事務(wù)中所有操作是不可再分割的原子單位。事務(wù)中所有操作要么都執(zhí)行成功,要么都執(zhí)行失敗

2.2 一致性(類(lèi)似能量守恒)

事務(wù)執(zhí)行后,數(shù)據(jù)庫(kù)狀態(tài)與其他業(yè)務(wù)規(guī)則保持一致,保證數(shù)據(jù)的一致性

2.3 隔離性

在并發(fā)操作中,不同事務(wù)之間應(yīng)該隔離開(kāi),使每個(gè)并發(fā)的事務(wù)不會(huì)相互干擾

2.4 持久性

一旦事務(wù)提交成功,事務(wù)中所有的數(shù)據(jù)操作都必須持久化到數(shù)據(jù)庫(kù)中,即使提交事務(wù)后,數(shù)據(jù)庫(kù)立馬崩潰,在數(shù)據(jù)庫(kù)重啟時(shí),也必須能通過(guò)某種機(jī)制恢復(fù)數(shù)據(jù)

三、隔離級(jí)別

3.1 事務(wù)級(jí)別(從低到高)

Read uncommitted:

讀未提交,一個(gè)事務(wù)可以讀取另一個(gè)未提交事務(wù)的數(shù)據(jù)。會(huì)產(chǎn)生臟讀。

Read committed:

讀提交,一個(gè)事務(wù)要等另一個(gè)事務(wù)提交后才能讀取數(shù)據(jù),會(huì)產(chǎn)生不可重復(fù)讀。

Repeatable read:

重復(fù)讀,開(kāi)始讀取數(shù)據(jù)(事務(wù)開(kāi)啟)時(shí),不再允許修改操作,可能出現(xiàn)幻讀。

Seriazable:

最高的事務(wù)隔離級(jí)別,該級(jí)別下事務(wù)串行化順序執(zhí)行,可避免臟讀、不可重復(fù)讀、幻讀,但是該事務(wù)級(jí)別效率低下,比較耗數(shù)據(jù)庫(kù)性能,一般不使用。

3.2 常用數(shù)據(jù)庫(kù)默認(rèn)級(jí)別:

Sql Server、Oracle 默認(rèn)事務(wù)隔離級(jí)別: Read committed

Mysql 默認(rèn)隔離級(jí)別是:Repeatable read

3.3 事務(wù)中可能出現(xiàn)的問(wèn)題:

臟讀(讀取了未提交的新事物,然后回滾了)

A 事務(wù)讀取了 B 事務(wù)中未提交的數(shù)據(jù), 如果事務(wù) B 回滾,則 A 讀取使用了錯(cuò)誤的數(shù)據(jù)。

不可重復(fù)讀(讀取了提交的新事物,指更新操作)

在對(duì)于數(shù)據(jù)庫(kù)中某個(gè)數(shù)據(jù),一個(gè)事務(wù)范圍內(nèi)多次查詢卻返回了不同的數(shù)據(jù)值,這是由于在查詢間隔,被另一個(gè)事務(wù)修改了。

幻讀(讀取了新提交的事務(wù),指增加刪除操作)

在事務(wù) A 多次讀取構(gòu)成中,事務(wù) B 對(duì)數(shù)據(jù)進(jìn)行了新增/刪除操作,導(dǎo)致 事務(wù) A 多次讀取的數(shù)據(jù)不一致。

第一類(lèi)事務(wù)丟失(回滾丟失)

事務(wù) A、B 同時(shí)執(zhí)行一個(gè)數(shù)據(jù),事務(wù) B 已經(jīng)提交,事務(wù) A 回滾了,B 的事務(wù)操作就因?yàn)槭聞?wù) A 回滾而丟失了

第二類(lèi)事務(wù)丟失(提交覆蓋丟失)

事務(wù) A、B 同時(shí)執(zhí)行一個(gè)數(shù)據(jù),兩個(gè)同時(shí)獲取到一個(gè)數(shù)據(jù),事務(wù) B 先提交, 事務(wù) A 后提交,則事務(wù) A 覆蓋了事務(wù) B

四、傳播特性

事務(wù)的傳播性分為以下三類(lèi),所有的都是給內(nèi)部方法配置

4.1 死活都不要事務(wù)

Never:外部方法沒(méi)有事務(wù)就非事務(wù)執(zhí)行,有就拋出異常

Not_Supported:外部方法沒(méi)有事務(wù)就非事務(wù)執(zhí)行,有就直接掛起,然后非事務(wù)執(zhí)行

4.2 可有可無(wú)的

Supported:外部方法有事務(wù)就用,沒(méi)有就算了

4.3 必須要有事務(wù)

Requires_new:不管外部方法有沒(méi)有事務(wù)都新建事務(wù),如果外部有,就將外部事務(wù)掛起

Nested:如果外部方法沒(méi)有事務(wù),就新建一個(gè)事務(wù),如果外部有事務(wù),就在外部事務(wù)中嵌套事務(wù)

Required:如果外部方法沒(méi)有事務(wù)就新建一個(gè)事務(wù),如果有,就加入外部方法的事務(wù),這個(gè)是最常用的,也是默認(rèn)的

Mandatory:如果外部方法沒(méi)有事務(wù)就拋出異常,如果有,就使用外部方法的事務(wù)

五、應(yīng)用

5.1 數(shù)據(jù)表

5.2 實(shí)體類(lèi)

import lombok.Data;
import javax.persistence.*;
@Data
@Entity
public class User {
    @Id
    @GeneratedValue
    private Integer id;
    private String name;
    private double money;
}

5.3 Service

package com.dily.study.work.service;
import com.dily.study.work.entity.User;
import com.dily.study.work.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired // 使用jpa
    private UserRepository userRepository;
    /**
     * 轉(zhuǎn)出
     *
     * @param fromName 從誰(shuí)轉(zhuǎn)出
     * @param money    轉(zhuǎn)出金額
     */
    public void out(String fromName, int money) {
        User user = userRepository.findByName(fromName);
        user.setMoney(user.getMoney() - money);
        userRepository.save(user);
    }
    /**
     * 轉(zhuǎn)入
     *
     * @param toName 轉(zhuǎn)到哪里
     * @param money  轉(zhuǎn)入金額
     */
    public void in(String toName, int money) {
        User user = userRepository.findByName(toName);
        user.setMoney(user.getMoney() + money);
        userRepository.save(user);
    }
     /**
     * 帶事務(wù)
     * 要么都成功,要么都失敗
     *
     * @param fromName 從哪里轉(zhuǎn)出
     * @param toName   轉(zhuǎn)入到哪里
     * @param money    金額
     */
    @Transactional
    public void transfer(String fromName, String toName, int money) {
        out(fromName, money);
        if (true) throw new RuntimeException("出錯(cuò)了");
        in(toName, money);
    }
    /**
     * 不帶事務(wù)
     * 只有轉(zhuǎn)出成功,轉(zhuǎn)入失敗
     *
     * @param fromName 從哪里轉(zhuǎn)出
     * @param toName   轉(zhuǎn)入到哪里
     * @param money    金額
     */
    public void transfer(String fromName, String toName, int money) {
        out(fromName, money);
        if (true) throw new RuntimeException("出錯(cuò)了");
        in(toName, money);
    }
}

事務(wù)的嵌套

// 在 UserService 中注入自己,因?yàn)槿绻麅?nèi)部調(diào)用自己的方法,事務(wù)注解不生效。
@Autowired
private UserService userService;
/**
 * 外層事務(wù),外層只轉(zhuǎn)出
 *
 * @param fromName 從哪里轉(zhuǎn)出
 * @param toName   轉(zhuǎn)入到哪里
 * @param money    金額
 */
@Transactional
public void laoda(String fromName, String toName, int money) {
    userService.out(fromName, money);
    if (true) throw new RuntimeException("出錯(cuò)了");
    userService.xiaodi(toName,money);
}
/**
 * 內(nèi)層事務(wù),內(nèi)層只轉(zhuǎn)入
 * 可以修改 propagation 的值來(lái)查看不同傳播類(lèi)型的效果
 *
 * @param toName   轉(zhuǎn)入到哪里
 * @param money    金額
 */
@Transactional(propagation = Propagation.MANDATORY)
public void xiaodi(String toName, int money) {
    if (true) throw new RuntimeException("出錯(cuò)了");
    userService.in(toName, money);
}

內(nèi)外部方法盡量避免操作同一張表,當(dāng)外部方法事務(wù)掛起時(shí),則外部操作的表會(huì)被加鎖,內(nèi)部方法事務(wù)則無(wú)法操作同一張表

到此這篇關(guān)于Spring事務(wù)管理零基礎(chǔ)入門(mén)的文章就介紹到這了,更多相關(guān)Spring事務(wù)管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論