首頁  >  文章  >  Java  >  SpringBoot事務管理實例分析

SpringBoot事務管理實例分析

WBOY
WBOY轉載
2023-05-13 14:13:20625瀏覽

1. 交易的定義

交易是由 N 步驟資料庫操作序列組成的邏輯執行單元,這系列操作要麼全部執行,要麼全部放棄執行。

2. 事務的特性

事務的ACID 特性:

  • 原子性:事務是應用程式中不可分割的最小執行體

  • 一致性:交易執行的結果必須使得資料從一個一致性狀態轉變為另一個一致性狀態

  • 隔離性:各個交易的執行互不干擾,任何交易的內部操作對其他交易都是隔離的

  • #持久性:交易一旦提交,對資料所做的任何修改都要記錄到永久記憶體中

3. 交易的隔離性

#常見的並發例外

  • 第一類遺失更新、第二類遺失更新

  • 髒讀、不可重複讀取、幻讀

常見的隔離等級

  • #Read Uncommitted:讀取未提交的資料

  • Read Commited:讀取已提交的資料

  • Repeatable Read:可重複讀取

  • Serializable:序列化

#第一類更新遺失:某一個交易的回滾,導致另一個交易已更新的資料遺失了。

第二類更新遺失:某一個交易的提交,導致另一個交易已更新的資料遺失了。

髒讀:某一個事務,讀取了另一個事務未提交的資料。

不可重複讀取:某一個事務,對同一個資料前後讀取的結果不一致。

幻讀:某一個事務,對同一個表前後查詢到的行數不一致。

不可重複讀取幻讀#Read Uncommitted是是是是是#Read Commited#是是是 ##否否是Repeatable Read
隔離等級 第一類遺失更新 #髒讀 第二類遺失更新

#否

#否

  • #4.事務管理

    實作機制
#悲觀鎖(資料庫)

  • 共享鎖(S鎖):事務A對某資料加了共用鎖定以後,其他交易只能對該資料加共用鎖,但不能加排他鎖

  • 排他鎖(X鎖):事務A對某資料加了排他鎖以後,其他事務對該資料既不能加共用鎖,也不能加排他鎖。

樂觀鎖定(自訂)

版本號、時間戳等
  • 在更新資料前,檢查版本號是否有變化。若發生變更則取消本次更新,否則就更新資料(版本號1)
  • Spring 交易管理
聲明式交易

  • 透過XML 配置,宣告某方法的事務特徵。

透過註解,宣告某方法的交易特徵。

######編程式事務############透過 TransactionTemplate管理事務,並透過它執行資料庫的操作。 ############5. 範例###
package com.nowcoder.community.service;
import com.nowcoder.community.dao.AlphaDao;
import com.nowcoder.community.dao.DiscussPostMapper;
import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.CommunityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;
@Service
//@Scope("prototype")
public class AlphaService {
    @Autowired
    private AlphaDao alphaDao;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DiscussPostMapper discussPostMapper;
    @Autowired
    private TransactionTemplate transactionTemplate;
    public AlphaService() {
//        System.out.println("实例化AlphaService");
    }
    @PostConstruct
    public void init() {
//        System.out.println("初始化AlphaService");
    }
    @PreDestroy
    public void destroy() {
//        System.out.println("销毁AlphaService");
    }
    public String find() {
        return alphaDao.select();
    }
    // REQUIRED: 支持当前事务(外部事务),如果不存在则创建新事务.
    // REQUIRES_NEW: 创建一个新事务,并且暂停当前事务(外部事务).
    // NESTED: 如果当前存在事务(外部事务),则嵌套在该事务中执行(独立的提交和回滚),否则就会REQUIRED一样.
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public Object save1() {
        // 新增用户
        User user = new User();
        user.setUsername("alpha");
        user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
        user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
        user.setEmail("alpha@qq.com");
        user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6198.png");
        user.setCreateTime(new Date());
        userMapper.insertUser(user);
        // 新增帖子
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle("Hello");
        post.setContent("新人报道!");
        post.setCreateTime(new Date());
        discussPostMapper.insertDiscussPost(post);
        Integer.valueOf("abc");
        return "ok";
    }
    public Object save2() {
        transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        return transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                // 新增用户
                User user = new User();
                user.setUsername("beta");
                user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
                user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
                user.setEmail("beta@qq.com");
                user.setHeaderUrl("https://cache.yisu.com/upload/information/20220823/112/6199.png");
                user.setCreateTime(new Date());
                userMapper.insertUser(user);
                // 新增帖子
                DiscussPost post = new DiscussPost();
                post.setUserId(user.getId());
                post.setTitle("你好");
                post.setContent("我是新人!");
                post.setCreateTime(new Date());
                discussPostMapper.insertDiscussPost(post);
                Integer.valueOf("abc");
                return "ok";
            }
        });
    }
}

以上是SpringBoot事務管理實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除