Spring事务常用知识点

一、使用事务的目的

把多个操作(多行代码)绑在一起,要么一起执行成功,要么一起执行失败,保证数据的完整与安全(多与数据库打交道)。

二、事务的概念

1.事务的定义:事务值得是逻辑上的一组操作,这组操作要么全部成功,要么全部失败。

2.四种事务特性(ACID):

(1)原子性 (atomicity):事务是一个不可分割的工作单位,事务中的操作要么都成功,要么都失败。
(2)一致性 (consistency):事务执行前后,数据保持一致,保证数据的完整性。
(3)隔离性 (isolation):多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务干扰。多个并发事务之间,数据要相互隔离。
(4)持久性(durability) :一个事务一旦执行完毕,它对数据库中数据的改变是永久性的,即使数据库发生故障也不应该对其有任何影响。

3.Spring事务管理高层抽象主要包括三个接口:

(1)PlatformTransactionManager:事务管理器

Spring为不同的持久化框架提供了不同的PlatformTransactionManager,如下

(2)TransactionDefinition:事务定义信息(隔离、传播、超时、只读)

(3)TransactionStatus:事务具体运行状态

4.五种隔离级别

(1)DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。(Mysql 默认repeatable_read, Oracle 默认read_commited)
(2)未提交读(read_uncommited) 
(3)已提交读 (read_commited)
(4)可重复读 (repeatable_read)
(5)串行化的 (serializable)

如果不考虑隔离性引发安全性问题: 
脏读 :一个事务读到了另一个事务的未提交的数据 
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致. 
虚幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.

这里写图片描述
5.七种事务传播行为 
   //保证在同一个事务中 
(1)PROPAGATION_REQUIRED:支持当前事务,如果不存在 就新建一个(默认) 
(2)PROPAGATION_SUPPORTS: 支持当前事务,如果不存在,就不使用事务 
(3)PROPAGATION_MANDATORY :支持当前事务,如果不存在,抛出异常 


   //保证不在同一个事务中 
(4)PROPAGATION_REQUIRES_NEW: 如果有事务存在,挂起当前事务,创建一个新的事务 
(5)PROPAGATION_NOT_SUPPORTED :以非事务方式运行,如果有事务存在,挂起当前事务 
(6)PROPAGATION_NEVER: 以非事务方式运行,如果有事务存在,抛出异常 

   //嵌套事务执行
(7)PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行

三、事务的使用方法

1.编程式事务管理:通过TransactionTemplate手动管理事务,在实际应用中很少使用,具体使用方法,略。

2.声明式事务管理(需要使用xml配置):通过AOP实现事务管理,代码侵入性小,推荐使用。

方法一:基于TransactionProxyFactoryBean,为每个事务管理的类配置一个TransactionProxyFactoryBean,进行增强。(很少使用)

方法二:基于AspectJ,在xml里配置,不需要在类里修改代码。(经常使用)

  • 相关xml文件:applicationContext.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:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

	<!-- 引入外部的属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 配置c3p0的连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.userName}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

	<!-- 配置业务层类 -->
	<bean id="accountService" class="cn.muke.spring.demo3.AccountServiceImpl">
		<property name="accountDAO" ref="accountDAO"></property>
	</bean>

	<!-- 配置DAO层类 -->
	<bean id="accountDAO" class="cn.muke.spring.demo3.AccountDAOImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

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

	<!-- 配置事务的通知/事务的增强 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		    <!-- 
		    	 * propagation	:事务的传播行为
				 * isolation	:事务的隔离级别
				 * readOnly		:只读
				 * rollback-for	:发生哪些异常回滚
				 * no-rollback-for:发生哪些异常不回滚
				 * timeout		:过期信息
		     -->
			<tx:method name="transfer" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>

	<!-- 配置切面 -->
	<aop:config>
		<aop:pointcut
			expression="execution(* cn.muke.spring.demo3.AccountService+.*(..))"
			id="pointcut1" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
	</aop:config>
</beans>

方法三:基于注解,配置简单,需要在事务管理的类上添加@Transactional注解。(经常使用)

  • 相关xml文件:applicationContext.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:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

	<!-- 引入外部的属性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 配置c3p0的连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.userName}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

	<!-- 配置业务层类 -->
	<bean id="accountService" class="cn.muke.spring.demo4.AccountServiceImpl">
		<property name="accountDAO" ref="accountDAO"></property>
	</bean>

	<!-- 配置DAO层类 -->
	<bean id="accountDAO" class="cn.muke.spring.demo4.AccountDAOImpl">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 配置事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 开启注解事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>	
</beans>
  • 相关Java文件:AccountServiceImpl.java
package cn.muke.spring.demo4;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * @author Administrator
 * 转账案例的业务层实现类
 * @Transactional(**)注解中的属性:
 * propagation	:事务的传播行为
 * isolation	:事务的隔离级别
 * readOnly		:只读
 * rollbackFor	:发生哪些异常回滚
 * noRollbackFor:发生哪些异常不回滚
 */
@Transactional	//要在哪个地方使用事务管理,就在哪个类上添加注解
public class AccountServiceImpl implements AccountService {
	//注入DAO层类
	private AccountDAO accountDAO;

	public void setAccountDAO(AccountDAO accountDAO) {
		this.accountDAO = accountDAO;
	}
	
	//注入事务管理模板
	private TransactionTemplate transactionTemplate;

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

	//out:转出账号,in:转入金额,money:转账金额
	public void transfer(String out, String in, Double money) {
		accountDAO.outMoney(out, money);
		int i=1/0;
		accountDAO.inMoney(in, money);
	}

}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值