一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解Spring學習之編程式事務管理

詳解Spring學習之編程式事務管理

2020-12-03 09:40顏洛濱 Java教程

本篇文章主要介紹了詳解Spring學習之編程式事務管理,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

在前面的內容,基本已經學習了事務的基本概念以及事務隔離級別等,接下來的幾個小節,將學習怎么使用Spring進行事務管理,在Spring中,對事務進行管理有多種方法,主要分別編程式和聲明式,本小節主要學習編程式事務管理,后面講學習Spring的聲明式事務管理

編程式事務管理

所謂的編程式事務管理,其實就是通過編寫代碼的方式來進行事務管理,也就是通過將事務管理的代碼硬編碼在代碼中從而達到事務管理的作用,不過Spring的事務管理不同于JDBC原始的事務管理,在JDBC中,對事務進行管理首先要關閉自動提交,然后采用手動配置的方式來控制提交以及異常時回滾,而在Spring中,主要是使用Spring的接口來管理,具體如下代碼所示

這里模擬銀行轉賬的業務,正如我們所知道的,轉賬其實就是從一個賬號減去金額并且給另外一個賬號增加對應的金額

Spring配置文件

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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.xsd">
 
   <!--開啟自動掃描-->
  <context:component-scan base-package="cn.xuhuanfeng.transaction"/>
 
  <!--配置數據源,這里采用dbcp-->
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="username" value="root"/>
    <property name="password" value="huanfeng"/>
  </bean>
 
  <!--配置JdbcTemplate-->
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--注入數據源-->
    <property name="dataSource" ref="dataSource"/>
  </bean>
 
  <!--配置事務管理-->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--注入數據源-->
    <property name="dataSource" ref="dataSource"/>
  </bean>
  <!--配置事務管理操作類-->
  <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <!--注入事務管理-->
    <property name="transactionManager" ref="transactionManager"/>
    <!--定義事務隔離級別,這里-1代表默認-->
    <property name="isolationLevel" value="-1"/>
    <!--配置傳播行為,0代表PROPAGATION_REQUIRED-->
    <property name="propagationBehavior" value="0"/>
    <!--由于進行讀寫操作,所以這里的只讀設置為false,默認也是false,所以可以不用設置-->
    <property name="readOnly" value="false"/>
  </bean>
</beans>

在配置事務隔離級別的時候,由于這里是采用整數的形式,而不是字符串,一開始在配置的時候有點摸不著頭腦,后來查看了對應的源代碼之后,發現了對應的常量,將其記錄如下

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 事務傳播行為
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
 
// 事務隔離級別
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
int TIMEOUT_DEFAULT = -1;

持久層代碼如下所示

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Repository
public class AccountDao {
 
  @Autowired
  private JdbcTemplate jdbcTemplate;
 
  public void transferIn(String name, double money){
    String sql = "update account set money = money + ? where name = ?";
 
    jdbcTemplate.update(sql, money, name);
  }
 
  public void transferOut(String name, double money){
    String sql = "update account set money = money - ? where name = ?";
 
    jdbcTemplate.update(sql, money, name);
  }
}

業務層代碼如下所示

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
@Service
public class AccountService {
 
  @Autowired
  private AccountDao accountDao;
 
  // 轉賬
  public void transfer(String fromName, String toName, double money){
 
    accountDao.transferOut(fromName, money);
    accountDao.transferIn(toName, money);
  }
}

對業務層代碼進行檢查測試,可以看到,結果是沒有問題的,也就是轉賬是成功的

如果此時在業務代碼執行過程中發生錯誤或者異常,那么結果會是如何呢

比如說,通過修改transfer代碼,手動模擬異常,如下所示

 
?
1
 
2
3
accountDao.transferOut(fromName, money);
int d = 1/0; // 除0異常
accountDao.transferIn(toName, money);

此時運行測試代碼,可以發現,數據出現了不一致,金額已經轉出了,但是由于在轉入之前發生了異常,所以無法轉入,導致了有一部分金額莫名其妙丟失了,這也就是為什么需要進行事務管理了。

對業務層代碼添加事務管理,如下所示

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Service
public class AccountService {
 
  @Autowired
  private AccountDao accountDao;
 
  // 配置事務管理操作類
  @Autowired
  private TransactionTemplate transactionTemplate;
 
 
  public void transfer(final String fromName,final String toName,final double money){
 
    // 通過transactionTemplate進行事務的管理
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
      @Override
      protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
        accountDao.transferOut(fromName, money);
        int d = 1/0; // 除0異常
        accountDao.transferIn(toName, money);
      }
    });
 
  }
}

此時再運行代碼,可以發現,不管是有沒有異常,數據的一致性都得到了保證,這也就是說,事務管理起了作用

上面的內容就是使用Spring進行事務管理的一種方式,不過這種方式是不太方便的,因為除了要配置事務管理操作類,也就是TransactionTemplate之外,當需要進行事務管理的時候,還需要在對應的代碼中為其編寫相應的管理代碼,如上所示,所以這種方式在日常的開發中比較少使用。

總結

本小節我們主要學習了如何在Spring配置事務管理器,并且通過編碼的方式,使用Spring的編程式事務管理對業務操作進行事務管理,不過這種方式使用起來不是很方便,所以使用的頻率非常少,接下來的小節我們將學習Spring的聲明式事務管理。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.jianshu.com/p/4a716cf71007?utm_source=tuicool&utm_medium=referral

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 性做久久久久久久久老女人 | 精品日本一区二区 | 亚洲人成影院午夜网站 | 亚洲精品动漫免费二区 | 四虎成人永久地址 | 日韩欧美中文字幕出 | 特黄特黄一级高清免费大片 | 69人成网站色www | 亚洲高清国产拍精品影院 | 欧美国产影院 | 人人人人人看碰人人免费 | 日韩ab| 小小水蜜桃视频高清在线播放 | 艾秋麻豆果冻剧传媒在线播放 | 关晓彤一级做a爰片性色毛片 | 日本在线小视频 | 欧美不卡一区二区三区 | 无码AV精品一区二区三区 | 欧美大片一区二区 | 草莓香蕉榴莲丝瓜秋葵绿巨人在线看 | 久见久热 这里只有精品 | 欧美亚洲影院 | 男人猛进猛出女人下面视频 | 精品国产免费一区二区三区 | 欧美日韩亚洲区久久综合 | 天堂网在线.www天堂在线视频 | 国产在视频线精品视频 | 800精品国产导航 | 99久久精品免费看国产情侣 | 亚洲尿尿 | 亚洲欧美日韩中文字幕网址 | 国产成人91高清精品免费 | 青青热久免费精品视频精品 | 草草线在成年免费视频网站 | 国产欧美成人不卡视频 | 色综合色综合 | 女教师系列三上悠亚在线观看 | 久久久久久免费高清电影 | 国产成人亚洲精品乱码在线观看 | 国产成人免费在线观看 | 亚洲 欧美 国产 日韩 字幕 |