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

SpringBoot 編程式事務(wù)使用及兩種實(shí)現(xiàn)方式

 更新時(shí)間:2024年12月20日 09:38:56   作者:lzz的編碼時(shí)刻  
編程式事務(wù)管理是通過編寫代碼來管理事務(wù),相對(duì)于聲明式事務(wù)(@Transactional注解),它提供了更細(xì)粒度的事務(wù)控制,這篇文章主要介紹了SpringBoot 編程式事務(wù)使用及兩種實(shí)現(xiàn)方式,需要的朋友可以參考下

1. 簡(jiǎn)介

編程式事務(wù)管理是通過編寫代碼來管理事務(wù),相對(duì)于聲明式事務(wù)(@Transactional注解),它提供了更細(xì)粒度的事務(wù)控制。在 SpringBoot 中,主要有兩種實(shí)現(xiàn)方式:

  • 使用 TransactionTemplate
  • 直接使用 TransactionManager

2. TransactionTemplate 方式

TransactionTemplate 是最簡(jiǎn)單的編程式事務(wù)實(shí)現(xiàn)方式,它對(duì)底層事務(wù) API 進(jìn)行了封裝,使用起來更加便捷。

2.1 基本配置

@Configuration
public class TransactionConfig {
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Bean
    public TransactionTemplate transactionTemplate() {
        TransactionTemplate template = new TransactionTemplate();
        template.setTransactionManager(transactionManager);
        // 設(shè)置默認(rèn)的事務(wù)傳播行為
        template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 設(shè)置默認(rèn)的事務(wù)隔離級(jí)別
        template.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
        // 設(shè)置默認(rèn)超時(shí)時(shí)間
        template.setTimeout(30);
        return template;
    }
}

2.2 基本使用示例

@Service
@Slf4j
public class UserService {
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private UserRepository userRepository;
    public User createUser(User user) {
        // 使用 execute 方法執(zhí)行有返回值的事務(wù)操作
        return transactionTemplate.execute(status -> {
            try {
                User savedUser = userRepository.save(user);
                // 模擬其他操作
                updateUserProfile(savedUser);
                return savedUser;
            } catch (Exception e) {
                // 手動(dòng)標(biāo)記事務(wù)回滾
                status.setRollbackOnly();
                log.error("創(chuàng)建用戶失敗", e);
                throw new RuntimeException("創(chuàng)建用戶失敗", e);
            }
        });
    }
    public void batchCreateUsers(List<User> users) {
        // 使用 executeWithoutResult 方法執(zhí)行無返回值的事務(wù)操作
        transactionTemplate.executeWithoutResult(status -> {
            try {
                for (User user : users) {
                    userRepository.save(user);
                }
            } catch (Exception e) {
                status.setRollbackOnly();
                log.error("批量創(chuàng)建用戶失敗", e);
                throw new RuntimeException("批量創(chuàng)建用戶失敗", e);
            }
        });
    }
}

3. TransactionManager 方式

直接使用 TransactionManager 提供了更細(xì)粒度的事務(wù)控制,但使用起來相對(duì)復(fù)雜。

3.1 基本使用示例

@Service
@Slf4j
public class OrderService {
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private OrderRepository orderRepository;
    public Order createOrder(Order order) {
        // 定義事務(wù)屬性
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setTimeout(30);
        // 獲取事務(wù)狀態(tài)
        TransactionStatus status = transactionManager.getTransaction(def);
        try {
            // 執(zhí)行業(yè)務(wù)邏輯
            Order savedOrder = orderRepository.save(order);
            // 處理訂單相關(guān)的其他操作
            processOrderDetails(savedOrder);
            // 提交事務(wù)
            transactionManager.commit(status);
            return savedOrder;
        } catch (Exception e) {
            // 回滾事務(wù)
            transactionManager.rollback(status);
            log.error("創(chuàng)建訂單失敗", e);
            throw new RuntimeException("創(chuàng)建訂單失敗", e);
        }
    }
}

3.2 嵌套事務(wù)示例

@Service
@Slf4j
public class PaymentService {
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private PaymentRepository paymentRepository;
    public void processPayment(Payment payment) {
        // 外部事務(wù)定義
        DefaultTransactionDefinition outerDef = new DefaultTransactionDefinition();
        outerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus outerStatus = transactionManager.getTransaction(outerDef);
        try {
            // 外部事務(wù)操作
            paymentRepository.save(payment);
            // 內(nèi)部事務(wù)定義
            DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
            innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
            TransactionStatus innerStatus = transactionManager.getTransaction(innerDef);
            try {
                // 執(zhí)行內(nèi)部事務(wù)操作
                processPaymentDetails(payment);
                transactionManager.commit(innerStatus);
            } catch (Exception e) {
                // 回滾內(nèi)部事務(wù)
                transactionManager.rollback(innerStatus);
                log.error("支付詳情處理失敗", e);
                throw e;
            }
            // 提交外部事務(wù)
            transactionManager.commit(outerStatus);
        } catch (Exception e) {
            // 回滾外部事務(wù)
            transactionManager.rollback(outerStatus);
            log.error("支付處理失敗", e);
            throw new RuntimeException("支付處理失敗", e);
        }
    }
}

4. 事務(wù)傳播行為

在編程式事務(wù)中,我們可以精確控制事務(wù)的傳播行為:

@Service
public class TransactionPropagationExample {
    @Autowired
    private TransactionTemplate transactionTemplate;
    public void demonstratePropagation() {
        // REQUIRED 傳播行為
        TransactionTemplate requiredTemplate = new TransactionTemplate(transactionTemplate);
        requiredTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // REQUIRES_NEW 傳播行為
        TransactionTemplate requiresNewTemplate = new TransactionTemplate(transactionTemplate);
        requiresNewTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 嵌套使用不同的傳播行為
        requiredTemplate.execute(outerStatus -> {
            // 外部事務(wù)邏輯
            requiresNewTemplate.execute(innerStatus -> {
                // 內(nèi)部事務(wù)邏輯(新的事務(wù))
                return null;
            });
            return null;
        });
    }
}

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

示例展示如何設(shè)置不同的事務(wù)隔離級(jí)別:

@Service
public class TransactionIsolationExample {
    @Autowired
    private PlatformTransactionManager transactionManager;
    public void demonstrateIsolation() {
        // 讀已提交隔離級(jí)別
        DefaultTransactionDefinition readCommittedDef = new DefaultTransactionDefinition();
        readCommittedDef.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        TransactionStatus readCommittedStatus = transactionManager.getTransaction(readCommittedDef);
        try {
            // 業(yè)務(wù)邏輯
            transactionManager.commit(readCommittedStatus);
        } catch (Exception e) {
            transactionManager.rollback(readCommittedStatus);
            throw e;
        }
        // 可重復(fù)讀隔離級(jí)別
        DefaultTransactionDefinition repeatableReadDef = new DefaultTransactionDefinition();
        repeatableReadDef.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
        // ... 類似的事務(wù)處理邏輯
    }
}

6. 最佳實(shí)踐

6.1 事務(wù)模板封裝

創(chuàng)建一個(gè)通用的事務(wù)處理模板:

@Component
@Slf4j
public class TransactionHelper {
    @Autowired
    private TransactionTemplate transactionTemplate;
    public <T> T executeInTransaction(TransactionCallback<T> action) {
        try {
            return transactionTemplate.execute(action);
        } catch (Exception e) {
            log.error("事務(wù)執(zhí)行失敗", e);
            throw new RuntimeException("事務(wù)執(zhí)行失敗", e);
        }
    }
    public void executeInTransactionWithoutResult(Consumer<TransactionStatus> action) {
        try {
            transactionTemplate.executeWithoutResult(action);
        } catch (Exception e) {
            log.error("事務(wù)執(zhí)行失敗", e);
            throw new RuntimeException("事務(wù)執(zhí)行失敗", e);
        }
    }
}
// 使用示例
@Service
public class BusinessService {
    @Autowired
    private TransactionHelper transactionHelper;
    public void doBusiness() {
        transactionHelper.executeInTransactionWithoutResult(status -> {
            // 業(yè)務(wù)邏輯
        });
    }
}

7. 常見問題與解決方案

7.1 事務(wù)超時(shí)處理

@Service
public class TimeoutExample {
    @Autowired
    private TransactionTemplate transactionTemplate;
    public void handleTimeout() {
        TransactionTemplate timeoutTemplate = new TransactionTemplate(transactionTemplate);
        timeoutTemplate.setTimeout(5); // 設(shè)置5秒超時(shí)
        try {
            timeoutTemplate.execute(status -> {
                // 可能超時(shí)的業(yè)務(wù)邏輯
                return null;
            });
        } catch (TransactionTimedOutException e) {
            // 處理超時(shí)異常
            log.error("事務(wù)執(zhí)行超時(shí)", e);
            throw new RuntimeException("事務(wù)執(zhí)行超時(shí)", e);
        }
    }
}

7.2 異常處理最佳實(shí)踐

@Service
public class ExceptionHandlingExample {
    @Autowired
    private TransactionTemplate transactionTemplate;
    public void handleExceptions() {
        try {
            transactionTemplate.execute(status -> {
                try {
                    // 業(yè)務(wù)邏輯
                    return null;
                } catch (BusinessException e) {
                    // 業(yè)務(wù)異常,標(biāo)記回滾
                    status.setRollbackOnly();
                    throw e;
                } catch (Exception e) {
                    // 其他異常,標(biāo)記回滾
                    status.setRollbackOnly();
                    throw new RuntimeException("未預(yù)期的錯(cuò)誤", e);
                }
            });
        } catch (Exception e) {
            // 統(tǒng)一異常處理
            handleException(e);
        }
    }
    private void handleException(Exception e) {
        if (e instanceof BusinessException) {
            // 處理業(yè)務(wù)異常
            log.warn("業(yè)務(wù)異常: {}", e.getMessage());
        } else {
            // 處理系統(tǒng)異常
            log.error("系統(tǒng)異常", e);
        }
        throw e;
    }
}

雖然編程式事務(wù)提供了更細(xì)粒度的控制,但在大多數(shù)情況下,聲明式事務(wù)(@Transactional)可能是更好的選擇。只有在需要特別精細(xì)的事務(wù)控制時(shí),才考慮使用編程式事務(wù)。

到此這篇關(guān)于SpringBoot 編程式事務(wù)使用的文章就介紹到這了,更多相關(guān)SpringBoot 編程式事務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot jasypt2.x與jasypt3.x的使用方式

    springboot jasypt2.x與jasypt3.x的使用方式

    在軟件開發(fā)中,將配置文件中的敏感信息(如數(shù)據(jù)庫密碼)進(jìn)行加密是保障安全的有效手段,jasypt框架提供了這一功能,支持通過加密工具類或命令行工具生成密文,并通過修改配置文件和啟動(dòng)參數(shù)的方式使用密文和密鑰,這樣即便配置文件被泄露
    2024-09-09
  • jstl之map,list訪問遍歷以及el表達(dá)式map取值的實(shí)現(xiàn)

    jstl之map,list訪問遍歷以及el表達(dá)式map取值的實(shí)現(xiàn)

    下面小編就為大家?guī)硪黄猨stl之map,list訪問遍歷以及el表達(dá)式map取值的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • IntelliJ?IDEA?2023.1.4?無法刷新Maven項(xiàng)目模塊的問題及解決方法

    IntelliJ?IDEA?2023.1.4?無法刷新Maven項(xiàng)目模塊的問題及解決方法

    這篇文章主要介紹了如何排查?IDEA?自身報(bào)錯(cuò)問題,本文以IntelliJ?IDEA?2023.1.4無法刷新項(xiàng)目Maven模塊的問題為例,給大家詳細(xì)講解,需要的朋友可以參考下
    2023-08-08
  • 解決SpringCloud下spring-boot-maven-plugin插件的打包問題

    解決SpringCloud下spring-boot-maven-plugin插件的打包問題

    這篇文章主要介紹了SpringCloud下spring-boot-maven-plugin插件的打包問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • 詳解springboot+mybatis-plue實(shí)現(xiàn)內(nèi)置的CRUD使用詳情

    詳解springboot+mybatis-plue實(shí)現(xiàn)內(nèi)置的CRUD使用詳情

    這篇文章主要介紹了詳解springboot+mybatis-plue實(shí)現(xiàn)內(nèi)置的CRUD使用詳情,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java中final關(guān)鍵字和final的4種用法

    Java中final關(guān)鍵字和final的4種用法

    這篇文章主要給大家分享的是?Java中final關(guān)鍵字和final的4種用法修飾類、修飾方法、修飾變量、修飾參數(shù),下面文章具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-11-11
  • Flutter 通過Clipper實(shí)現(xiàn)各種自定義形狀的示例代碼

    Flutter 通過Clipper實(shí)現(xiàn)各種自定義形狀的示例代碼

    這篇文章主要介紹了Flutter 通過Clipper實(shí)現(xiàn)各種自定義形狀的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • MyEclipse安裝JS代碼提示的教程(Spket插件)

    MyEclipse安裝JS代碼提示的教程(Spket插件)

    本篇文章主要介紹了MyEclipse安裝JS代碼提示的教程(Spket插件),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解

    Java內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解

    這篇文章主要為大家詳細(xì)介紹了Java因?yàn)閮?nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助
    2022-11-11
  • Java拼接字符串時(shí)如何去掉最后一個(gè)多余的逗號(hào)

    Java拼接字符串時(shí)如何去掉最后一個(gè)多余的逗號(hào)

    當(dāng)我們遍歷拼接字符串的時(shí)候,最后會(huì)多出一個(gè)我們添加的字符(比如逗號(hào)),下面通過實(shí)例代碼給大家介紹Java拼接字符串時(shí)去掉最后一個(gè)多余的逗號(hào),感興趣的朋友跟隨小編一起看看吧
    2024-12-12

最新評(píng)論