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

Spring?模擬轉(zhuǎn)賬開發(fā)實戰(zhàn)小結(jié)

 更新時間:2025年05月19日 09:03:55   作者:lyrhhhhhhhh  
轉(zhuǎn)賬是金融類應(yīng)用的核心場景之一,涉及付款方扣減金額和收款方增加金額兩個關(guān)鍵操作,本文主要介紹了Spring?模擬轉(zhuǎn)賬開發(fā)實戰(zhàn)小結(jié),具有一定的參考價值,感興趣的可以了解一下

一、轉(zhuǎn)賬業(yè)務(wù)場景分析

轉(zhuǎn)賬是金融類應(yīng)用的核心場景之一,涉及付款方扣減金額收款方增加金額兩個關(guān)鍵操作。在開發(fā)中需解決以下問題:

  • 業(yè)務(wù)層與數(shù)據(jù)層解耦:通過分層架構(gòu)(Service 層調(diào)用 Dao 層)實現(xiàn)邏輯分離。
  • 數(shù)據(jù)庫事務(wù)管理:確保兩個操作要么同時成功,要么同時失敗,避免資金不一致。
  • 代碼復(fù)用與簡化:利用 Spring 框架的模板類和依賴注入機制,減少樣板代碼。

二、基于 Spring 的轉(zhuǎn)賬業(yè)務(wù)開發(fā)(第一種方式)

 1. 分層架構(gòu)設(shè)計

 (1)Service 層:定義業(yè)務(wù)邏輯

// 接口:聲明轉(zhuǎn)賬方法
public interface AccountService {
    void pay(String out, String in, double money); // 付款人、收款人、金額
}

// 實現(xiàn)類:調(diào)用Dao完成轉(zhuǎn)賬
public class AccountServiceImpl implements AccountService {
    private AccountDao accountDao; // 注入Dao層對象

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void pay(String out, String in, double money) {
        accountDao.outMoney(out, money); // 付款方扣款
        accountDao.inMoney(in, money); // 收款方加款
    }
}

(2)Dao 層:操作數(shù)據(jù)庫

// 接口:定義數(shù)據(jù)庫操作
public interface AccountDao {
    void outMoney(String out, double money); // 扣款
    void inMoney(String in, double money); // 加款
}

// 實現(xiàn)類:使用JdbcTemplate操作數(shù)據(jù)庫
public class AccountDaoImpl implements AccountDao {
    private JdbcTemplate jdbcTemplate; // 注入JdbcTemplate

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void outMoney(String out, double money) {
        jdbcTemplate.update("update account set money=money-? where name=?", money, out);
    }

    @Override
    public void inMoney(String in, double money) {
        jdbcTemplate.update("update account set money=money+? where name=?", money, in);
    }
}

2. Spring 配置文件(applicationContext_dao1.xml)

<beans ...>
    <!-- 加載數(shù)據(jù)庫配置 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <!-- 配置Druid連接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    
    <!-- 配置JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 配置Service和Dao,注入依賴 -->
    <bean id="accountService" class="com.qcbyjy.demo2.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>
    
    <bean id="accountDao" class="com.qcbyjy.demo2.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
</beans>

3. 測試代碼

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_dao1.xml")
public class Demo2 {
    @Autowired
    private AccountService accountService;

    @Test
    public void testPay() {
        accountService.pay("熊大", "熊二", 100); // 模擬熊大給熊二轉(zhuǎn)賬100元
    }
}

三、Dao 層的簡化寫法(第二種方式)

 1. 繼承 JdbcDaoSupport

Spring 提供JdbcDaoSupport抽象類,內(nèi)置JdbcTemplate管理,可簡化 Dao 層代碼:

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void outMoney(String out, double money) {
        // 通過getJdbcTemplate()獲取模板對象
        this.getJdbcTemplate().update("update account set money=money-? where name=?", money, out);
    }

    @Override
    public void inMoney(String in, double money) {
        this.getJdbcTemplate().update("update account set money=money+? where name=?", money, in);
    }
}

2. Spring 配置優(yōu)化

 無需顯式配置JdbcTemplate,直接注入數(shù)據(jù)源(dataSource)即可:

<bean id="accountDao" class="com.qcbyjy.demo3.AccountDaoImpl">
    <property name="dataSource" ref="dataSource"/> <!-- 注入數(shù)據(jù)源 -->
</bean>

原理JdbcDaoSupport會自動根據(jù)dataSource創(chuàng)建JdbcTemplate,避免手動綁定模板對象。

四、轉(zhuǎn)賬業(yè)務(wù)的事務(wù)管理(關(guān)鍵!)

為什么需要事務(wù)?

假設(shè)轉(zhuǎn)賬過程中,付款方扣款成功后系統(tǒng)崩潰,收款方未加款,會導(dǎo)致資金丟失。事務(wù)確保兩個操作要么都成功,要么都回滾。

1. 未加事務(wù)的問題演示

  • 場景:付款方余額不足時,扣款操作拋出異常,但收款方已加款。
  • 代碼問題:默認(rèn)情況下,Spring 的JdbcTemplate操作是自動提交的,異常不會回滾。

2. 添加事務(wù)控制 

 (1)在 Spring 配置中啟用事務(wù)管理

<beans ...>
    <!-- 配置事務(wù)管理器 -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/> <!-- 綁定數(shù)據(jù)源 -->
    </bean>

    <!-- 啟用注解事務(wù) -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

 (2)在 Service 方法上添加@Transactional注解

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;

    // 聲明該方法需要事務(wù)支持
    @Transactional
    @Override
    public void pay(String out, String in, double money) {
        accountDao.outMoney(out, money); // 若此處拋出異常,兩個操作都會回滾
        accountDao.inMoney(in, money);
    }
}

3. 事務(wù)關(guān)鍵特性

  • 原子性:兩個更新操作視為一個不可分割的整體。
  • 隔離性:避免其他事務(wù)看到中間狀態(tài)(通過數(shù)據(jù)庫隔離級別實現(xiàn))。
  • 傳播行為:默認(rèn)REQUIRED(當(dāng)前有事務(wù)則加入,無則創(chuàng)建新事務(wù))。

五、兩種 Dao 實現(xiàn)方式對比

六、總結(jié)與最佳實踐

核心流程總結(jié)

  • 分層設(shè)計:Service 層處理業(yè)務(wù)邏輯,Dao 層封裝數(shù)據(jù)庫操作。
  • 依賴注入:通過 Spring 配置文件管理對象依賴,避免硬編碼。
  • 事務(wù)控制:使用@Transactional注解確保數(shù)據(jù)一致性,必須配置事務(wù)管理器。
  • 連接池優(yōu)化:優(yōu)先使用 Druid 等開源連接池,提升數(shù)據(jù)庫性能。

常見問題與解決方案

  • 事務(wù)不生效:檢查是否配置事務(wù)管理器、注解是否添加在 public 方法上、是否使用了代理對象。
  • SQL 注入風(fēng)險:使用JdbcTemplate的參數(shù)化查詢(?占位符),避免拼接 SQL。
  • 異常處理:在 Service 層捕獲異常并按需回滾(通過TransactionAspectSupport.currentTransactionStatus().setRollbackOnly())。

到此這篇關(guān)于Spring 模擬轉(zhuǎn)賬開發(fā)實戰(zhàn)小結(jié)的文章就介紹到這了,更多相關(guān)Spring 模擬轉(zhuǎn)賬開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • JavaTCP上傳圖片代碼實例

    JavaTCP上傳圖片代碼實例

    今天小編就為大家分享一篇關(guān)于JavaTCP上傳圖片代碼實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • java?JIT調(diào)優(yōu)的實現(xiàn)

    java?JIT調(diào)優(yōu)的實現(xiàn)

    JIT編譯器調(diào)優(yōu)方法包括啟用JIT日志、優(yōu)化熱點代碼、循環(huán)展開、內(nèi)聯(lián)優(yōu)化、逃逸分析以及使用性能分析工具等,本文主要介紹了java?JIT調(diào)優(yōu)的實現(xiàn),感興趣的可以了解一下
    2025-02-02
  • 基于spring+hibernate+JQuery開發(fā)之電子相冊(附源碼下載)

    基于spring+hibernate+JQuery開發(fā)之電子相冊(附源碼下載)

    本篇文章介紹了,基于spring+hibernate+JQuery開發(fā)之電子相冊(附源碼下載)。需要的朋友參考下
    2013-05-05
  • Spring?Boot?2.x升3.x的那些事

    Spring?Boot?2.x升3.x的那些事

    最近項目需求,準(zhǔn)備從Spring Boot 2.x升級到3.x,升級后發(fā)現(xiàn)編譯器報了一堆錯誤,本文主要介紹了Spring?Boot?2.x升3.x的那些事,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • SpringBoot整合Flyway實現(xiàn)數(shù)據(jù)庫的初始化和版本管理操作

    SpringBoot整合Flyway實現(xiàn)數(shù)據(jù)庫的初始化和版本管理操作

    Flyway?是一款開源的數(shù)據(jù)庫版本管理工具,它可以很方便的在命令行中使用,或者在Java應(yīng)用程序中引入,用于管理我們的數(shù)據(jù)庫版本,這篇文章主要介紹了SpringBoot整合Flyway實現(xiàn)數(shù)據(jù)庫的初始化和版本管理,需要的朋友可以參考下
    2023-06-06
  • Java?Stream比較兩個List的差異并取出不同的對象四種方法

    Java?Stream比較兩個List的差異并取出不同的對象四種方法

    今天開發(fā)一個需求時要對A和B兩個List集合遍歷,并比較出集合A有,而集合B沒有的值,下面這篇文章主要給大家介紹了關(guān)于Java?Stream比較兩個List的差異并取出不同對象的四種方法,需要的朋友可以參考下
    2024-01-01
  • Java設(shè)計模式中的橋接模式

    Java設(shè)計模式中的橋接模式

    這篇文章主要介紹了Java設(shè)計模式中的橋接模式,其是一種結(jié)構(gòu)型設(shè)計模式,是指將實現(xiàn)與抽象放在兩個不同的類層次中,使兩個層次可以獨立改變
    2022-07-07
  • MyBatis查詢返回Map示例代碼

    MyBatis查詢返回Map示例代碼

    這篇文章主要給大家介紹了關(guān)于MyBatis查詢返回Map的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • java獲取本地文件和遠(yuǎn)程文件的方式代碼示例

    java獲取本地文件和遠(yuǎn)程文件的方式代碼示例

    這篇文章主要給大家介紹了關(guān)于java獲取本地文件和遠(yuǎn)程文件的方式,我們項目開發(fā)的時候,經(jīng)常會讀取文件,如果文件在本服務(wù)器,則直接用new File()讀取即可,但是有時候需要遠(yuǎn)程讀取文件,需要的朋友可以參考下
    2023-08-08
  • 詳解Java中Duration類的使用方法

    詳解Java中Duration類的使用方法

    Duration類通過秒和納秒相結(jié)合來描述一個時間量,最高精度是納秒。本文將通過示例詳細(xì)為大家講講Duration類的使用,需要的可以參考一下
    2022-05-05

最新評論