Spring——編程式事務管理


開發(fā)工具及軟件
IntelliJ IDEA 2017 + Maven + Spring + MySQL

Spring編程式事務管理需要手動編寫代碼來進行事務管理
這里用一個簡單轉賬Demo來舉例

1.配置文件

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>spring_transaction</groupId>
  <artifactId>spring_transaction</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>spring_transaction Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>

    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.10</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.10.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>


  </dependencies>

  <build>
    <finalName>spring_transaction</finalName>
  </build>
</project>

log4j.properties

# Configure logging for testing: optionally with log file
log4j.rootLogger=WARN, stdout
# log4j.rootLogger=WARN, stdout, logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

mysql.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/pay?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

pay.sql

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'aaa', '1000');
INSERT INTO `account` VALUES ('2', 'bbb', '1000');
INSERT INTO `account` VALUES ('3', 'ccc', '1000');

2、接口設置

通常我們使用Spring是基于接口開發(fā)的下隧,所以這里先創(chuàng)建一個Service接口和一個DAO層接口:

AccountService.java

package com.zbnfy.demo1.service;
/**
 * Created by zbnfy on 2017/10/7.
 * 轉賬案例的業(yè)務接口
 */
public interface AccountService {
    /**
     * @param out 轉出賬號
     * @param in  轉入賬號
     * @param money  轉賬金額
     */
    public void transfer(String out,String in,Double money);
}

AccountDao.java

package com.zbnfy .demo1.dao;

/**
 * Created by zbnfy on 2017/10/7.
 */
public interface AccountDao {
    /**
     * @param out 轉出賬號
     * @param money  轉出金額
     */
    public void outMonry(String out,Double money);

    /**
     * @param in  轉入賬號
     * @param money  轉入金額
     */
    public void inMoney(String in,Double money);  
}

3.實現(xiàn)類

AccountServiceImpl.java

package com.zbnfy.demo1.service;

import com.zbnfy.demo1.dao.AccountDao;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * Created by zbnfy on 2017/10/7.
 * 轉賬案例的實現(xiàn)類
 */
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

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


    //注入事務管理的模板
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * @param out 轉出賬號
     * @param in  轉入賬號
     * @param money  轉賬金額
     */
    public void transfer(final String out,final String in,final Double money) {
        accountDao.outMonry(out,money);
        accountDao.inMoney(in,money);
    }
}

AccountDaoImpl.java

package com.zbnfy.demo1.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by zbnfy on 2017/10/7.
 */
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
    /**
     * @param out 轉出賬號
     * @param money  轉出金額
     */
    public void outMonry(String out, Double money) {
        String sql = "update account set money = money - ? where name = ?";
        this.getJdbcTemplate().update(sql,money,out);
    }

    /**
     * @param in  轉入賬號
     * @param money  轉入金額
     */
    public void inMoney(String in, Double money) {
        String sql = "update account set money = money + ? where name = ?";
        this.getJdbcTemplate().update(sql,money,in);
    }
}

4.測試類

package com.zbnfy.demo1.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

/**
 * Created by zbnfy on 2017/10/7.
 * Spring編程式測試類
 */

@RunWith(SpringJUnit4ClassRunner.class)  //JUnit4測試
@ContextConfiguration("classpath:spring-context.xml")  //Spring配置文件
public class SpringDemo1 {
    //測試業(yè)務層
    @Resource(name = "accountService")
    private AccountService accountService;

    @Test
    public void demo1() {
        accountService.transfer("aaa","bbb",200d);
    }
}

5.Spring配置

spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--引入外部的數(shù)據(jù)庫連接文件-->
    <context:property-placeholder location="mysql.properties"/>

    <!-- 數(shù)據(jù)庫連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--配置業(yè)務層-->
    <bean id="accountService" class="com.zbnfy.demo1.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>  //業(yè)務層控制DAO層
        <!--注入事務管理的模板-->
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

    <!--配置DAO層-->
    <bean id="accountDao" class="com.zbnfy.demo1.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>  //控制數(shù)據(jù)庫連接池
    </bean>

    <!--配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>   //控制數(shù)據(jù)庫連接池
    </bean>

    <!--配置事務管理的模板:Spring為了簡化事務管理的代碼而提供的類-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>  //事務模板類控制事務管理器
    </bean>

</beans>

6.總結

編程式事務管理方法允許在源代碼編程的方式下管理事務备闲×裥ィ基于TransactionTemplate編程恬叹,雖然帶來了極大地靈活性识樱,但是難以維護。所以實際開發(fā)中一般不用這種方式砌滞。


參考資料:
慕課網(wǎng)http://www.imooc.com/video/9331

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末歇父,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子搀玖,更是在濱河造成了極大的恐慌余境,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灌诅,死亡現(xiàn)場離奇詭異芳来,居然都是意外死亡,警方通過查閱死者的電腦和手機猜拾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門即舌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挎袜,你說我怎么就攤上這事顽聂》什眩” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵紊搪,是天一觀的道長蜜葱。 經(jīng)常有香客問我,道長耀石,這世上最難降的妖魔是什么牵囤? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮滞伟,結果婚禮上揭鳞,老公的妹妹穿的比我還像新娘。我一直安慰自己梆奈,他們只是感情好野崇,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亩钟,像睡著了一般乓梨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上径荔,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天督禽,我揣著相機與錄音,去河邊找鬼总处。 笑死,一個胖子當著我的面吹牛睛蛛,可吹牛的內容都是我干的鹦马。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼忆肾,長吁一口氣:“原來是場噩夢啊……” “哼荸频!你這毒婦竟也來了?” 一聲冷哼從身側響起客冈,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤旭从,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后场仲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體和悦,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年渠缕,在試婚紗的時候發(fā)現(xiàn)自己被綠了鸽素。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡亦鳞,死狀恐怖馍忽,靈堂內的尸體忽然破棺而出棒坏,到底是詐尸還是另有隱情,我是刑警寧澤遭笋,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布坝冕,位于F島的核電站,受9級特大地震影響瓦呼,放射性物質發(fā)生泄漏徽诲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一吵血、第九天 我趴在偏房一處隱蔽的房頂上張望谎替。 院中可真熱鬧,春花似錦蹋辅、人聲如沸钱贯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秩命。三九已至,卻和暖如春褒傅,著一層夾襖步出監(jiān)牢的瞬間弃锐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工殿托, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霹菊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓支竹,卻偏偏與公主長得像旋廷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子礼搁,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理饶碘,服務發(fā)現(xiàn),斷路器馒吴,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,827評論 6 342
  • 1. Java基礎部分 基礎部分的順序:基本語法扎运,類相關的語法,內部類的語法饮戳,繼承相關的語法豪治,異常的語法,線程的語...
    子非魚_t_閱讀 31,645評論 18 399
  • 都說感情是兩個人的事莹捡,你們一起經(jīng)歷過了那么多鬼吵,縱然有萬般的痛苦和歡樂但是你依然堅信自己的這份感情和執(zhí)著,在決定要...
    七月ll閱讀 266評論 0 0
  • G:【閱讀:個體崛起的時代】什么是自由職業(yè)態(tài)篮赢? 1齿椅、定義:自由職業(yè)態(tài)的自由琉挖,是指自己的能力達到了能與企業(yè)自由交易的...
    牽著上帝去流浪閱讀 179評論 0 0