天天看點

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

1、聲明式事務

2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹

3、注解式事務聲明

4、xml配置式事務聲明

5、Spring整合Web

1、聲明式事務

事務分為聲明式和程式設計式兩種:

聲明式事務:聲明式事務是指通過注解的形式對事務的各種特性進行控制和管理。

編碼式(程式設計式)事務:指的是通過編碼的方式實作事務的聲明。

1.1、編碼方式實作事務:

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

1.2、聲明式事務環境搭建

1.2.2、準備測試資料庫

##建立tx資料庫
drop database if exists `tx`;
CREATE database `tx`;
##切換tx資料庫
USE `tx`;

##删除使用者表
DROP TABLE IF EXISTS `user`;
##建立使用者表
CREATE TABLE `user` (
  `id` int primary key auto_increment,	
  `username` varchar(50) NOT NULL,
  `money` int(11) DEFAULT NULL
);
##插入資料
insert  into `user`(`username`,`money`) values ('張三',1000),('李四',1000);

##删除圖書表
drop table if exists `book`;
##建立圖書表
create table `book`(
    `id` int primary key auto_increment,
    `name` varchar(500) not null,
    `stock` int
);
##插入資料
insert into book(`name`,`stock`) values('java程式設計思想',100),('C++程式設計思想',100);

##檢視資料
select * from book;
select * from user;
           

1.2.2、建立一個Java工程,導入Jar包

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

JavaBean對象

public class Book {

	private Integer id;
	private String name;
private int stock;

public class User {

	private Integer id;
	private String username;
	private int money;
           

Dao們

@Repository
public class BookDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public int updateBook() {
		String sql = "update book set name = '**我被修改了!**' where id = 1";
		return jdbcTemplate.update(sql);
	}

}
           
@Repository
public class UserDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public int updateUser() {
		String sql = "update user set username = '**我被修改了**' where id = 1";
		return jdbcTemplate.update(sql);
	}

}
           

Service代碼

@Service
public class TransactionService {

	@Autowired
	private UserDao userDao;

	@Autowired
	private BookDao bookDao;

	public void updateTwoTable() {
		userDao.updateUser();
		bookDao.updateBook();
	}

}
           

1.3、測試Service的預設事務

實驗1:測試service服務層的預設事務

@ContextConfiguration(locations = "classpath:application.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTest {

	@Autowired
	private DataSource dataSource;

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	private TransactionService transactionService;

	@Test
	public void testDataSource() throws Exception {
		System.out.println(dataSource.getConnection());
	}
	
	@Test
	public void testJdbcTempalte() throws Exception {
		System.out.println( jdbcTemplate );
	}
	
	@Test
	public void testTransaction() throws Exception {
		transactionService.updateTwoTable();
	}

}
           

異常的示範

public void updateTwoTable() {
		userDao.updateUser();
		int i = 12 / 0;
		bookDao.updateBook();
	}
           

結果:

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

但結果卻是一張表更新了,另一種表未更新就發生異常,導緻兩張表不能同步,經典案例就是銀行的轉賬,這邊轉過去了,對方沒有收到。這裡就要用到事務來處理了,要是在同一個事務中有一處出錯,整個事務都復原,進而阻止這種非一緻性的更新操作。

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹

PlatformTransactionManager接口,提供所有事務操作規範。我們使用DataSource資料庫連接配接池,使用的事務管理器是DataSourceTransactionManager類

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

注:和Javaweb的Filter、jdk動态代理、aop、Utilsjdbc的原理一樣分三層結構處理業務

3、注解式事務聲明

3.1使用Spring的注解式聲明事務管制

實驗2:測試Spring的聲明式事務

先導入AOP包,因為Spring的底層事務使用到了aop功能

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

spring-aop-4.0.0.RELEASE.jar

spring-aspects-4.0.0.RELEASE.jar

配置Spring的事務需要的切面類DataSourceTransactionManager

<!-- 配置DataSourceTransactionManager事務管理器===事務的切面類 -->
	<bean id="transactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />	
	</bean>
           

在Spring的配置檔案中加入tx名稱空間

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

在Spring的配置檔案中

<!-- 配置啟用spring的事務注解驅動@Transactional -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
           

還需要在Service的事務方法中添加@Transactioaln注解

@Transactional
	public void updateTwoTable() {
		userDao.updateUser();
		int i = 12 / 0;
		bookDao.updateBook();
	}
           

3.2、noRollbackFor和noRollbackForClassName測試不復原的異常

實驗3:noRollbackFor和noRollbackForClassName測試不復原的異常

/**
	 * noRollbackFor=ArithmeticException.class 表示當接收到數學異常之後。不復原<br/>
	 * noRollbackForClassName="java.lang.ArithmeticException" 表示當接收到指定字元串表示的全類名的異常的時候,不復原事務
	 */
	@Transactional(noRollbackFor=ArithmeticException.class)
	public void updateTwoTable() {
		userDao.updateUser();
		int i = 12 / 0;
		bookDao.updateBook();
	}
           

Book:

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

User表:

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

注:spring預設復原的是運作時異常RuntimeException和RuntimeException的子異常

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

3.3、自定義設定復原異常

實驗5:rollbackFor和rollbackForClassName復原的異常

Spring預設復原的是RuntimeException,運作時異常或運作時異常的子異常

/**
	 * spring預設復原的是運作時異常RuntimeException和RuntimeException的子異常<br/>
	 * rollbackFor=FileNotFoundException.class	表示FileNotFoundException也會復原
	 * rollbackForClassName="java.io.FileNotFoundException" 表示當出現配置字元串所表示的全類名的異常的時候。也會復原事務
	 * @throws FileNotFoundException
	 * 
	 */
	@Transactional(rollbackFor=FileNotFoundException.class)
	public void updateTwoTable() throws FileNotFoundException {
		userDao.updateUser();
		int i = 0;
		if (i == 0) {//java.io.FileNotFoundException
			throw new FileNotFoundException("sadf");
		}
		bookDao.updateBook();
	}
           

3.3、事務的隻讀屬性

實驗4:測試readOnly隻讀屬性

/**
	 * readOnly 如果值為true。表示隻支援查詢操作。不支援寫操作
* <br/>如果設定為false,支援全部
	 */
	@Transactional(readOnly=true)
	public void updateTwoTable() throws FileNotFoundException {
		userDao.updateUser();
		bookDao.updateBook();
	}
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

3.4、事務逾時屬性timeout(秒為機關)

timeout=3表示操作不能超過3秒,否在就包錯

@Transactional(timeout=3)
	public void updateTwoTable() throws FileNotFoundException {
		userDao.updateUser();
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		bookDao.updateBook();
	}
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

3.5、事務的傳播特性propagation

什麼是事務的傳播行為:

當事務方法(XxxService())被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運作,也可能開啟一個新事務,并在自己的事務中運作。

事務的傳播行為可以由傳播屬性指定。Spring定義了7種類傳播行為。

事務的傳播特性,有以下幾種類型:(常用的就前兩種,是以下面進行這兩種的測試)required(預設的)

Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

3.6、注解示範事物傳播特性

因為事務方法是被其他事務方法調用是以,添加幾個事務方法進行測試

UserService

BookService

TransactionService

實驗1:大小事務傳播特性都是REQUIRED、

實驗2:大小事務傳播特性都是REQUIRES_NEW

實驗3:大事務是REQUIRED,小事務都是REQUIRES_NEW

實驗4:大事務是REQUIRED,小1REQUIRED,小2REQUIRES_NEW

實驗5:大事務是REQUIRED,小1REQUIRES_NEW,小2REQUIRED

實驗1:大小事務傳播特性都是REQUIRED

@Transactional(propagation = Propagation.REQUIRED)
	public void multiUpdate() {
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateBook() {
        @Transactional(propagation=Propagation.REQUIRED)
        public void updateUser() {
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

實驗2:大小事務傳播特性都是REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void multiUpdate()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

實驗3:大事務是REQUIRED,小事務都是REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRED)
	public void multiUpdate()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

實驗4:大事務是REQUIRED,小1REQUIRED,小2REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRED)
	public void multiUpdate()
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

實驗5:大事務是REQUIRED,小1REQUIRES_NEW,小2REQUIRED

@Transactional(propagation = Propagation.REQUIRED)
	public void multiUpdate()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateUser()
           
Spring詳解四之聲明式事務1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web1、聲明式事務2、Spring事務引入的分析------PlatformTransactionManager類簡單介紹3、注解式事務聲明4、xml配置式事務聲明5、Spring整合Web

4、xml配置式事務聲明

去掉。所有@Transactional的注解。

當然注解有的功能,xml也可以實作

<!-- 配置DataSourceTransactionManager事務管理器===事務的切面類 -->
	<bean id="transactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />	
	</bean>

	<!-- 事務特性 -->
	<tx:advice id="tx_advice" transaction-manager="transactionManager">
		<!-- 配置事務特性 -->
		<tx:attributes>
			<tx:method name="multiUpdate" propagation="REQUIRED"/>
			<tx:method name="updateBook" propagation="REQUIRES_NEW"  />
			<tx:method name="updateUser" propagation="REQUIRED"/>
			<tx:method name="*" read-only="true"/>
		</tx:attributes>
	</tx:advice>

	<!-- 配置aop代理,一定要有切入點表達式 -->
	<aop:config>
		<aop:advisor advice-ref="tx_advice" pointcut="execution(* com.atguigu.service.*Service.*(..))" />
	</aop:config>
           

總結:使用jdbcTemplate或者是事務管理器 屬性都要引用資料源,因為都是在資料庫連接配接的基礎上操作的。

總結:注解方式和配置檔案方式的事務

(1)、無論哪種方式,預設都是propagation="REQUIRED";方式

(2)、無論哪種方式,預設值都是:transaction-manager="transactionManager"

(3)、無論哪種方式,都要有事務管理器---管理事務的切面類-DataSourceTransactionManager

advice - advisor :建議 ,顧問

配置檔案情況下:一、(為什麼用aop.jar包?因為事務的底層是用aop的三層結構實作的,學習aop的主要作用就是處理事務)

<!-- 配置aop代理 -->
	<aop:config>
		<aop:advisor advice-ref="tx_advice" pointcut="execution(* com.atguigu.service.*Service.*(..))" />
	</aop:config>
           

二、還有事務的特性配置

注解方法情況下:在Spring的配置檔案中

<!-- 配置		啟用spring的事務(tx:)		注解(annotation)	驅動(driven )@Transactional -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
           

這裡的transaction-manager="transactionManager"一般如果切面類的id值是transactionManager,這裡就可以省略了,陰謀在事務的注解驅動裡,預設是這個值的。但如果切面類的管理器的id不是這個值,這裡就一定要加上對應的值了。

5、Spring整合Web

5.1在web工程中添加Spring的jar包。

Spring的核心包

spring-beans-4.0.0.RELEASE.jar

spring-context-4.0.0.RELEASE.jar

spring-core-4.0.0.RELEASE.jar

spring-expression-4.0.0.RELEASE.jar

aop包

spring-aop-4.0.0.RELEASE.jar(注解,包掃描)

spring-aspects-4.0.0.RELEASE.jar

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

JDBC-ORM包

spring-jdbc-4.0.0.RELEASE.jar

spring-orm-4.0.0.RELEASE.jar

spring-tx-4.0.0.RELEASE.jar(事務管理)

Spring的web整合包

spring-web-4.0.0.RELEASE.jar

測試包

spring-test-4.0.0.RELEASE.jar

整合Spring和Web容器分兩個步驟:

1、導入spring-web-4.0.0.RELEASE.jar

2、在web.xml配置檔案中配置org.springframework.web.context.ContextLoaderListener(直接提示導入,無需記憶)監聽器監聽ServletContext的初始化

3、在web.xml配置檔案中配置contextConfigLocation上下文參數。配置Spring配置檔案的位置,以用于初始化Spring容器

5.2在web.xml中配置

<context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
           

5.3擷取WebApplicationContext上下文對象的方法如下:

方法一(官方推薦):

WebApplicationContextUtils.getWebApplicationContext(getServletContext())

方法二(不推薦):

getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

Spring詳解三之AOP與資料通路

常用spring開發jar包即額外包下載下傳