Spring框架簡介⑩
事務的特性(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系列.
智能推薦
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開發人員中越來越受歡迎...
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壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...