偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring Boot 事務(wù)同步機(jī)制:從原理到實(shí)戰(zhàn)

云計(jì)算 分布式
在分布式系統(tǒng)和復(fù)雜業(yè)務(wù)場(chǎng)景中,我們經(jīng)常需要在事務(wù)完成后執(zhí)行一些額外操作,比如發(fā)送消息通知、更新緩存、記錄審計(jì)日志等。

前言

在分布式系統(tǒng)和復(fù)雜業(yè)務(wù)場(chǎng)景中,我們經(jīng)常需要在事務(wù)完成后執(zhí)行一些額外操作,比如發(fā)送消息通知、更新緩存、記錄審計(jì)日志等。

事務(wù)同步機(jī)制概述

事務(wù)同步機(jī)制是Spring事務(wù)管理的重要擴(kuò)展點(diǎn),允許我們?cè)谑聞?wù)的不同階段(如提交前、提交后、回滾后等)執(zhí)行自定義邏輯。這種機(jī)制的核心價(jià)值在于:

  • 保證操作的原子性:確保后續(xù)操作僅在事務(wù)成功提交后執(zhí)行
  • 維護(hù)數(shù)據(jù)一致性:避免事務(wù)未完成時(shí)外部系統(tǒng)感知到中間狀態(tài)
  • 簡(jiǎn)化業(yè)務(wù)代碼:將事務(wù)相關(guān)的輔助操作與核心業(yè)務(wù)邏輯解耦

Spring通過(guò)TransactionSynchronization接口定義了事務(wù)同步的標(biāo)準(zhǔn),而TransactionSynchronizationAdapter作為其適配器實(shí)現(xiàn),提供了默認(rèn)空實(shí)現(xiàn),讓開(kāi)發(fā)者只需重寫(xiě)需要的方法,簡(jiǎn)化了使用成本。

核心方法解析

TransactionSynchronizationAdapter實(shí)現(xiàn)了TransactionSynchronization接口,核心方法對(duì)應(yīng)事務(wù)生命周期的關(guān)鍵節(jié)點(diǎn):

方法名

執(zhí)行時(shí)機(jī)

典型用途

beforeCommit(boolean readOnly)

事務(wù)提交前

最后一次數(shù)據(jù)校驗(yàn)、設(shè)置提交標(biāo)記

afterCommit()

事務(wù)成功提交后

發(fā)送消息、更新緩存、調(diào)用外部系統(tǒng)

afterCompletion(int status)

事務(wù)完成后(無(wú)論成功失?。?/p>

資源清理、記錄最終狀態(tài)

beforeCompletion()

事務(wù)完成前(提交 / 回滾前)

預(yù)清理資源、狀態(tài)記錄

afterRollback()

事務(wù)回滾后

回滾補(bǔ)償操作、通知失敗

代碼實(shí)現(xiàn)

Repository 接口

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

消息服務(wù)(模擬外部系統(tǒng)調(diào)用)

@Service
public class MessageService {
    /**
     * 模擬發(fā)送歡迎消息
     */
    public void sendWelcomeMessage(String email, String username) {
        System.out.printf("【消息服務(wù)】向 %s(%s) 發(fā)送歡迎消息:歡迎注冊(cè)我們的平臺(tái)!%n", username, email);
    }
    
    /**
     * 模擬發(fā)送注冊(cè)失敗通知
     */
    public void sendRegistrationFailedMessage(String email) {
        System.out.printf("【消息服務(wù)】向 %s 發(fā)送注冊(cè)失敗通知:很抱歉,注冊(cè)過(guò)程出現(xiàn)異常%n", email);
    }
}

業(yè)務(wù)邏輯

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private MessageService messageService;

    /**
     * 用戶(hù)注冊(cè)(帶事務(wù)同步操作)
     */
    @Transactional
    public User register(User user) {
        // 1. 保存用戶(hù)(核心業(yè)務(wù))
        User savedUser = userRepository.save(user);
        System.out.println("【用戶(hù)服務(wù)】用戶(hù)注冊(cè)成功,ID:" + savedUser.getId());
        
        // 2. 注冊(cè)事務(wù)同步器
        registerTransactionSynchronization(savedUser);
        
        // 模擬業(yè)務(wù)異常(可注釋/打開(kāi)測(cè)試事務(wù)回滾場(chǎng)景)
        // if ("test@rollback.com".equals(user.getEmail())) {
        //     throw new RuntimeException("模擬注冊(cè)異常,觸發(fā)事務(wù)回滾");
        // }
        
        return savedUser;
    }
    
    /**
     * 注冊(cè)事務(wù)同步器,定義事務(wù)不同階段的操作
     */
    private void registerTransactionSynchronization(User user) {
        // 檢查當(dāng)前是否存在事務(wù)上下文
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                
                // 事務(wù)提交后執(zhí)行:發(fā)送歡迎消息
                @Override
                public void afterCommit() {
                    messageService.sendWelcomeMessage(user.getEmail(), user.getUsername());
                }
                
                // 事務(wù)回滾后執(zhí)行:發(fā)送失敗通知
                @Override
                public void afterRollback() {
                    messageService.sendRegistrationFailedMessage(user.getEmail());
                }
                
                // 事務(wù)完成后(無(wú)論成?。﹫?zhí)行:記錄最終狀態(tài)
                @Override
                public void afterCompletion(int status) {
                    String statusDesc = switch (status) {
                        case STATUS_COMMITTED -> "已提交";
                        case STATUS_ROLLED_BACK -> "已回滾";
                        case STATUS_UNKNOWN -> "未知狀態(tài)";
                        default -> "異常狀態(tài)";
                    };
                    System.out.printf("【事務(wù)同步】用戶(hù) %s 的注冊(cè)事務(wù)最終狀態(tài):%s%n", user.getUsername(), statusDesc);
                }
            });
        } else {
            throw new RuntimeException("當(dāng)前無(wú)活躍事務(wù),無(wú)法注冊(cè)同步器");
        }
    }
}

注意事項(xiàng)

  • 事務(wù)上下文依賴(lài):必須在活躍的事務(wù)上下文中注冊(cè)同步器(即@Transactional方法內(nèi)部),否則TransactionSynchronizationManager.isSynchronizationActive()會(huì)返回false,導(dǎo)致注冊(cè)失敗。
  • 執(zhí)行順序:若注冊(cè)多個(gè)同步器,默認(rèn)按注冊(cè)順序執(zhí)行??赏ㄟ^(guò)setOrder(int)方法指定執(zhí)行優(yōu)先級(jí)(值越小越先執(zhí)行)。
  • Spring4.2+提供的@TransactionalEventListener是更簡(jiǎn)潔的替代方案,基于事件機(jī)制實(shí)現(xiàn),但TransactionSynchronizationAdapter更靈活,支持更細(xì)粒度的事務(wù)階段控制。
@Autowired
private ApplicationEventPublisher publisher;

@Transactional(rollbackFor = Exception.class)
public void add(SomeEntity entity) {
    // 業(yè)務(wù)操作
    publisher.publishEvent(entity);
}

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(SomeEntity entity) {
    // 事務(wù)提交后執(zhí)行的邏輯
}

責(zé)任編輯:武曉燕 來(lái)源: 一安未來(lái)
相關(guān)推薦

2025-04-02 07:29:14

2025-08-29 01:45:00

2024-03-27 10:14:48

2019-05-27 14:40:43

Java同步機(jī)制多線程編程

2017-12-15 10:20:56

MySQLInnoDB同步機(jī)制

2011-11-23 10:09:19

Java線程機(jī)制

2025-10-27 01:22:00

HTTP接口API

2016-09-20 15:21:35

LinuxInnoDBMysql

2020-04-28 22:12:30

Nginx正向代理反向代理

2022-02-28 10:05:12

組件化架構(gòu)設(shè)計(jì)從原組件化模塊化

2012-07-27 10:02:39

C#

2012-07-09 09:25:13

ibmdw

2024-07-05 08:32:36

2025-04-03 00:03:00

數(shù)據(jù)內(nèi)存網(wǎng)絡(luò)

2025-05-28 08:45:00

2025-09-29 01:50:00

2024-06-28 08:45:58

2021-05-11 07:51:30

React ref 前端

2025-09-28 04:22:00

RAGSpring AI人工智能

2025-09-29 05:00:00

Linux線程棧內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)