SSM学习之Spring的事务管理

一、Spring事务管理概述

1、事务管理的核心接口

详细介绍请点击其他

2、事务管理的方式

Spring中的事务管理分为两种方式:一种是传统的编程式事务管理,另一种是声明式事务管理。
编程式事务管理:是通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚。
声明式事务管理:是通过AOP技术实现的事务管理,其主要思想是将事务管理作为一个“切面”代码单独编写,然后通过AOP技术将事务管理的“切面”代码织入到业务目标类中。

二、声明式事务管理

1)基于XML方式的声明式事务

基于XML方式的声明式事务管理是通过在配置文件中配置事务规则的相关声明来实现的。
Spring2.0以后,提供了tx命名空间来配置事务,tx命名空间下提供了<tx: advice>元素来配置事务的通知(增强处理)。

<!-- 5. 编写通知:对事物进行通知,需要编写对切入点和具体执行事务细节 -->
     	<tx:advice id="txAdvice" transaction-manager="transactionManager">
     	<tx:attributes>
     		<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
     	</tx:attributes>
     	</tx:advice>

配置<tx:advice>时,要指定id属性(配置文件中的唯一标识)和transaction-manager属性(用于指定事务管理器)。<tx:advice>中有<tx:attributes>子元素。子元素中有<tx:method>元素,用于配置执行事务的细节。 <tx:method>元素的属性描述如下:

属性是否必须默认值描述
name与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法如:‘*’、’get*’、’handle*’、’* Order’等等。
propagationREQUIRED事务传播行为
isolationDEFAULT事务隔离级别
timeout-1事务超时的时间(以秒为单位) ,如果为-1,则说明事务超时时间由底层的事务系统所决定
read-onlyfalse事务是否只读
rollback-for所有运行期异常回滚触发事务回滚的Excepiton,用异常名称的片段进行匹配,可以设置多个,用逗号分开,如Exception1,Exception2
norollback-for所有检查型异常不回滚不触发事务回滚的Excepiton,用异常名称的片段进行匹配,可以设置多个,用逗号分开,如Exception1,Exception2

案例:通过xml方式实现Spring的声明式事务管理 模拟一个赠送积分的项目,体现事务管理

导入相关JAR包
在这里插入图片描述
在原有数据库中添加jf属性类型设为int(11),所有用户默认1000积分。

在User类中添加jf及其setter、getter方法

private Integer jf;
public Integer getJf() {
	return jf;
}
public void setJf(Integer jf) {
	this.jf = jf;
}

在UserDao接口中添加transfer()方法,三个参数

	public void transfer(String outUser,String inUser,Integer jf);

在UserDaoImpl类中实现并完善方法this关键字用于当前类

	//赠送积分
	public void transfer(String outUser, String inUser, Integer jf) {
	//接收积分
	this.jdbcTemplate.update("update user set jf=jf+? where username=?",jf,inUser);
	//模拟系统运行中突发性问题
	int i=1/0;
	//送出积分
	this.jdbcTemplate.update("update user setjf=jf-? where username=?",jf,outUser);
	}

修改applicationContext.xml
1、配置数据源
2、配置jdbc模板
3、定义id为userDao的bean
4、事务管理器,依赖于数据源
5、编写通知:对事物进行通知,需要编写对切入点和具体执行事务细节
6、编写aop,让spring自动对目标生成代理,需要使用AspectJ

<?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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        		http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        		http://www.springframework.org/schema/aop
        		http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        		http://www.springframework.org/schema/tx
        		http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
        		http://www.springframework.org/schema/context
        		http://www.springframework.org/schema/context/spring-context-4.3.xsd">
     	<!-- 1、配置数据源 -->	
     	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     		<!-- 数据库驱动 -->
     		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
     		<!-- 连接数据库的url -->
     		<property name="url" value="jdbc:mysql://localhost:3306/db_spring" />
     		<!-- 连接数据库的用户名 -->
     		<property name="username" value="root" />
     		<!-- 连接数据库的密码 -->
     		<property name="password" value="root" />
     	</bean>	
     	<!-- 2、配置jdbc模板 -->
     	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     		<!-- 默认必须使用数据源 -->
     		<property name="dataSource" ref="dataSource" />
     	</bean>
     	<!-- 3.定义id为userDao的bean -->
     	<bean id="userDao" class="com.ssm.jdbc.UserDaoImpl">
     		<property name="jdbcTemplate" ref="jdbcTemplate" />
     	</bean>
     	<!-- 4. 事务管理器,依赖于数据源 -->
     	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
     		<property name="dataSource" ref="dataSource"  />
     	</bean>
     	<!-- 5. 编写通知:对事物进行通知,需要编写对切入点和具体执行事务细节 -->
     	<tx:advice id="txAdvice" transaction-manager="transactionManager">
     	<tx:attributes>
     		<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
     	</tx:attributes>
     	</tx:advice> 
     	<!-- 6. 编写aop,让spring自动对目标生成代理,需要使用AspectJ -->
     	<aop:config>
     		<aop:pointcut expression="execution(* com.ssm.jdbc.*.*(..))" id="txPointCut" />
     		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
     	</aop:config>
</beans>

定义了id为transactionManager的事务管理器,下面用编写的通知来声明事务,最后用声明aop的方式让Spring自动生成代理。

编写测试类

package com.ssm.jdbc;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionTest {
	@Test
	public void XMLTest(){
		ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao=(UserDao) app.getBean("userDao");
		userDao.transfer("admin1", "HQX", 100);
		System.out.println("赠送积分成功:");
	}
}

在这里插入图片描述
Junit控制台中报出了“/ y zero”的算术异常信息。在执行赠送积分操作后,查看 user表中的数据,即zhangsan和lisi的积分没有发生变化,这说明 Spring中的事务管理配置已经生效。

2)基于Annotation方式的声明式事务

Spring的声明式事务管理还可以通过 Annotation(注解)的方式来实现。这种方式的使用非常简单,开发者只需做两件事情:

(1)在 Spring容器中注册事务注解驱动;
<tx:annotation-driven transaction-manager="transactionManager" />
(2)在需要使用事务的 Spring Bean类或者Bean类的方法上添加注解@Transactional。

@Transactional注解中常用参数说明

参数名称功能描述
value用于需要使用的事务管理器,默认为“”,其别名为transactionManager
propagationpropagation用于指定事务的传播行为,默认值为 REQUIRED
isolationisolation用于指定事务的隔离规则,默认值为DEFAULT
readOnly该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
rollbackFor该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
rollbackForClassName该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称:@Transactional(rollbackForClassName=“RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,“Exception”})
noRollbackFor该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
noRollbackForClassName该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=“RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,“Exception”})
timeout该属性用于设置事务的超时秒数,默认值为-1表示永不超时

src下新建applicationContext-annotation.xml

<?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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        		http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        		http://www.springframework.org/schema/aop
        		http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        		http://www.springframework.org/schema/tx
        		http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
        		http://www.springframework.org/schema/context
        		http://www.springframework.org/schema/context/spring-context-4.3.xsd">
     	<!-- 1、配置数据源 -->	
     	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     		<!-- 数据库驱动 -->
     		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
     		<!-- 连接数据库的url -->
     		<property name="url" value="jdbc:mysql://localhost:3306/db_spring" />
     		<!-- 连接数据库的用户名 -->
     		<property name="username" value="root" />
     		<!-- 连接数据库的密码 -->
     		<property name="password" value="root" />
     	</bean>	
     	<!-- 2、配置jdbc模板 -->
     	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     		<!-- 默认必须使用数据源 -->
     		<property name="dataSource" ref="dataSource" />
     	</bean>
     	<!-- 3.定义id为userDao的bean -->
     	<bean id="userDao" class="com.ssm.jdbc.UserDaoImpl">
     		<property name="jdbcTemplate" ref="jdbcTemplate" />
     	</bean>
     	<!-- 4. 事务管理器,依赖于数据源 -->
     	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
     		<property name="dataSource" ref="dataSource"  />
     	</bean>
     	<!-- 5. 注册事务管理器驱动 -->
     	<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

添加测试类

@Test
	public void AnnocationTest(){
		ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao=(UserDao) app.getBean("userDao");
		userDao.transfer("admin1", "HQX", 100);
		System.out.println("赠送积分成功:");
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点份炸鸡778

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值