• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • Spring框架簡介⑩

    標簽: spring  java

    事務的特性(ACID):

    A: Atomic 原子性

    表示組成一個事務的多個對數據庫的操作為一個不可分割的單元, 只有所有的操作都成功才算成功, 整個事務才會提交, 其中任何一個操作失敗了都會導致整個操作失敗, 事務則會回滾

    C: Consistency 一致性

    事務操作成功后, 數據庫所處的狀態和業務規則是一致(不變)的, 如果A賬戶給B賬戶匯100, 則A賬戶要減去100, B賬戶要加上100 兩個賬戶的總額是不變的

    I: Isolation 隔離性

    在多個對數據庫操作相同的數據并發時, 不同的事務有自己的數據空間, 事務與事務之間不受干擾(不是絕對的), 干擾程度受數據庫或者操作事務的隔離級別來決定, 隔離級別越高, 干擾就越低, 數據的一致性就越好, 而并發性則越差.

    D: Durability 持久性

    一旦事務提交成功, 數據就被持久化到數據庫, 不可以回滾, 重啟/關機都不會丟失數據了.

     

    原子性由Spring的傳播特性來控制, 一致性和隔離性由數據庫的隔離級別來控制.

     

    事務控制

    配置文件的配置(第一頭文件配置, 第二事務管理器的配置, 第三開啟事務注解驅動)

    這是我的項目結構圖:

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-3.2.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
    
        <!-- 配置屬性文件的位置 -->
        <context:property-placeholder location="classpath:jdbc.properties"/>
        
        <!-- 配置數據源 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        
            <!-- 采用${xxx}的形式讀取屬性文件中對應key的內容 -->
            <property name="driverClassName" value="${driverClassName}"></property>
            <property name="url" value="${url}"></property>
            <property name="username" value="${uname}"></property>
            <property name="password" value="${pword}"></property>
            <!-- 初始化連接數 -->
            <property name="initialSize" value="${initialSize}"></property>
            <!-- 最大連接數 -->
            <property name="maxActive" value="${maxActive}"></property>
            <!-- 最大空閑連接數 -->
            <property name="maxIdle" value="${maxIdle}"></property>
            <!-- 最小空閑連接數 -->
            <property name="minIdle" value="${minIdle}"></property>
        </bean>
        
        <bean id="orderDao" class="com.rl.spring.dao.impl.OrderDaoImpl">
            <property name="ds" ref="dataSource"></property>
        </bean>
        <bean id="detailDao" class="com.rl.spring.dao.impl.DetailDaoImpl">
            <property name="ds" ref="dataSource"></property>
        </bean>
        
        <bean id="orderService" class="com.rl.spring.service.impl.OrderServiceImpl">
            <property name="orderDao" ref="orderDao"></property>
        </bean>
        
        <bean id="detailService" class="com.rl.spring.service.impl.DetailServiceImpl">
            <property name="orderDao" ref="orderDao"></property>
            <property name="detailDao" ref="detailDao"></property>
        </bean>
        
        <!-- 定義事務管理器 -->    
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 配置事務管理的注解驅動 -->
        <tx:annotation-driven transaction-manager="txManager"/>
    </beans>

    下面只粘貼實現類的代碼

    OrderDaoImpl:

    package com.rl.spring.dao.impl;
    
    import javax.sql.DataSource;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.rl.spring.dao.OrderDao;
    import com.rl.spring.model.Order;
    
    public class OrderDaoImpl implements OrderDao {
    
        private DataSource ds;
        
        private JdbcTemplate jt;
        
        public void setDs(DataSource ds) {
            this.ds = ds;
            this.jt = new JdbcTemplate(ds);
        }
    
        @Override
        public int saveOrder(Order order) {
            String sql = "insert into t_order values(null, ?)";
            jt.update(sql, new Object[] {order.getTotalPrice()});
            return jt.queryForInt("SELECT LAST_INSERT_ID()");//該行代碼的作用是讓數據庫返回主鍵
        }
    }
    

    DetailDaoImpl

    package com.rl.spring.dao.impl;
    
    import javax.sql.DataSource;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.rl.spring.dao.DetailDao;
    import com.rl.spring.model.Detail;
    import com.rl.spring.model.Order;
    
    public class DetailDaoImpl implements DetailDao {
    
        private DataSource ds;
        
        private JdbcTemplate jt;
        
        public void setDs(DataSource ds) {
            this.ds = ds;
            this.jt = new JdbcTemplate(ds);
        }
    
        @Override
        public void saveDetail(Detail detail) {
            String sql = "insert into t_detail values(null, ?, ?, ?)";
            jt.update(sql, new Object[] {detail.getItemName(), detail.getQuantity(), detail.getOrderId()});
        }
    }
    

    OrderServiceImpl(較簡單, 省略粘貼上來)

    DetailServiceImpl:

    package com.rl.spring.service.impl;
    
    import org.springframework.transaction.annotation.Transactional;
    
    import com.rl.spring.dao.DetailDao;
    import com.rl.spring.dao.OrderDao;
    import com.rl.spring.model.Detail;
    import com.rl.spring.model.Order;
    import com.rl.spring.service.DetailService;
    
    public class DetailServiceImpl implements DetailService {
    
        DetailDao detailDao;
        
        OrderDao orderDao;
        
        public void setOrderDao(OrderDao orderDao) {
            this.orderDao = orderDao;
        }
    
        public void setDetailDao(DetailDao detailDao) {
            this.detailDao = detailDao;
        }
    
        @Transactional//事務管理注解
        @Override
        public void saveOrderAndDetail(Order order, Detail detail) {
            Integer orderId = orderDao.saveOrder(order);
            detail.setOrderId(orderId);
            int i = 1/0;//設置運行期異常, 由于配置了Transactional注解, 所以事務會全部回滾
            detailDao.saveDetail(detail);
        }
    }
    

    測試代碼:

    package com.rl.spring.test;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.rl.spring.model.Detail;
    import com.rl.spring.model.Order;
    import com.rl.spring.service.DetailService;
    import com.rl.spring.service.OrderService;
    
    @RunWith(value=SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations= {"classpath:ApplicationContext.xml"})
    public class TestSpring {
    	
        @Autowired
        OrderService orderService;
        
        @Autowired
        DetailService detailService;
        
        @Test
        public void test() {
            Order order = new Order();
            order.setTotalPrice(100);
            
            Detail detail = new Detail();
            detail.setItemName("HUAWEI");
            detail.setQuantity(1);
            detailService.saveOrderAndDetail(order, detail);
        }
    }

    @Transactional注解的本質是事務的傳播特性, 下面詳講事務的傳播特性

    Spring的傳播特性

    Required傳播特性(80%以上使用該傳播特性)

    業務方法需要在一個事務中運行, 如果一個方法已經處在一個事務中那么就加入到這個事務中, 否則就會創建一個新事務

    如下圖:

    傳播特性可配置:

    Never傳播特性(極少使用):

    指定的業務方法絕對不能在事務中運行, 如果在事務中運行了, 則會拋異常, 只有業務方法沒有事務才會正常執行.

    MANDATORY傳播特性:

    與Never相反, 只能在一個已經存在的事務中執行, 不能自己發起事務, 如果業務方法沒有事務的情況下, 則拋異常

    SUPPORTS傳播特性:

    如果業務方法已經在某個事務中被調用, 則業務方法就成為事務的一部分, 如果業務方法沒有在某個事務中被調用, SUPPORTS也支持該業務方法的執行(一句話, 開事務我就用事務, 不開事務我就不用事務, 但都可以執行)

    NOT_SUPPORTED傳播特性:

    永遠不支持事務(在有事務中該事務會被掛起)

    REQUIRES_NEW傳播特性:

    永遠使用自己創建的事務(如果已經存在事務則掛起它, 自己新創建), 假如自己new出來的這個事務回滾了, 是不會影響到另一個被掛起的事務的.

    NESTED傳播特性:

    主要區分于內外部事務, 如果內部事務做回滾, 是不會影響到外部事務的(因為NESTED會設置一個事務保存點, 回滾到該保存點后繼續執行外部事務); 而如果是外部事務做回滾, 該內外部事務全部回滾.

    這點跟REQUIRES_NEW有區別, REQUIRES_NEW是不管是否內外部事務都互不影響.

     

    ====================================================

    Spring系列暫時寫到這里, 后續抽時間更一下事務的隔離級別, 接下來會更Hibernate系列.

     

    版權聲明:本文為ip_JL原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/ip_JL/article/details/81509852

    智能推薦

    Spring框架學習_Spring簡介(02)

    這里寫自定義目錄標題 簡單了解框架 第一章 Spring 概述 # 1.1 Spring概述 # 1.2 Spring模塊 簡單了解框架 第一章 Spring 概述 # 1.1 Spring概述 1)Spring是一個開源框架 2)Spring為簡化企業級開發而生,使用Spring,JavaBean就可以實現很多以前要靠EJB才能實現的功能。同樣的功能,在EJB中要通過繁瑣的配置和復雜的代碼才能夠...

    Spring框架簡介以及環境搭建

    1.spring概述 Spring是一個開源框架,Spring是于2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是為了解決企業應用開發的復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為 J2E...

    安全框架(一)Spring Security 簡介

    安全框架: Spring Security+Shiro+OAuth2在一個項目里面 github地址: https://github.com/ZiCheng-Web/springboot-security 在 Java 開發領域常見安全框架有 Shiro 和Spring Security。 Shiro 是個一個輕量級的安全管理框架,提供了認證、授權、 會話管理、密碼管理、緩存管理等功能,。 Spr...

    Spring框架學習01:簡介和IoC

    一、Spring框架簡介 1.Spring歷史 2002,首次推出了spring框架的雛形,interface21框架! spring框架即以interface21框架為基礎,經過重新設計,并不斷豐富其內涵,于2003年3月24日發布了1.0正式版。 Rod Johnson,spring framework創始人,著名作者。很難想象Rod Johnson的學歷,真的讓好多人大吃一驚,他是悉尼大學的...

    Spring 框架簡介及簡單環境搭建

    Spring 框架簡介 概述 Spring 是最受歡迎的企業級 Java 應用程序開發框架 Spring 框架是一個開源的 Java 平臺,它最初是由 Rod Johnson 編寫的 Spring 是輕量級的框架 宗旨 不產生新技術,使原有的技術使用更加方便 核心 Ioc/DI:控制反轉/依賴注入 AOP:面向切面編程 聲明式事務 Spring Framework Runtime Test:Spr...

    猜你喜歡

    portlet_Spring Portlet MVC框架簡介

    本文是由三部分組成的文章系列的第一篇文章,“開發供在IBM WebSphere Portal中使用的Spring Portlet MVC Framework應用程序”。 這是一篇高級文章; 盡管不需要任何高級知識,但您應該熟悉開發JSR-168 Portlet的基礎知識,并且對Spring框架有基本的了解。 在過去的幾年中, Spring框架在J2EE開發人員中越來越受歡迎...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡