Spring事务管理(业务层)

事务控制
  • 编程式
  • 注解式
  • 声明式

ACID原则

  • Atomicity:原子性
  • Consistency:一致性
  • Isolation:隔离性
  • Durability:持久性

TransactionDefinition定义的事务传播属性

编号传播属性描述
1PROPAGATION_REQUIRED如果存在事务,则支持当前事务。如果没有当前事务,则开启新的事务
2PROPAGATION_SUPPORTS如果存在事务,则支持当前事务。如果没有当前事务,则非事务地执行
3PROPAGATION_MANDATORY如果存在事务,则支持当前事务。如果没有活动事务,则抛出异常
4PROPAGATION_REQUIRED_NEW总是开启新的事务。如果已经存在事务,则将已存在的事务挂起
5PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务
6PROPAGATION_NEVER总是非事务地执行,如果存在活动事务,则抛出异常
7PROPAGATION_NESTED如果存在活动事务,则将其运行在一个嵌套事务中。如果没哟活动的事务,则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

TransactionDefinition定义的事务隔离级别

编号事务隔离级别描述
1ISOLATION_DEFAULT默认的隔离级别,使用数据库默认的事务隔离级别
2ISOLATION_READ_UNCOMMITTED最低的隔离级别,允许其他事务访问当前的事务未提交的数据。会产生脏读、不可重复读,幻读
3ISOLATION_READ_COMMITTED当前事务修改的数据提交后才能被下一个事务读取。下一个事务不能读取当前事务未提交的数据。可防止脏读,可能出现不可重复读、幻读
4ISOLATION_REPEATABLE_READ可防止脏读、不可重复读,可能出现幻读
5ISOLATION_SERIALIZABLE最可靠的事务隔离级别,事务处理为顺序执行。可防止脏读、不可重复读幻读

说明:其他代码同上一篇

编程式事务控制

配置数据源,spring-jdbc.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	<!-- 在开发之中C3P0数据库连接池使用非常广泛 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"/>	<!-- 驱动程序 -->
		<property name="jdbcUrl" value="jdbc:mysql:*****/mldn"/>	<!-- 连接地址 -->
		<property name="user" value="root"/>	<!-- 用户名 -->
		<property name="password" value="*****"/>	<!-- 密码 -->
		<property name="maxPoolSize" value="1"/>	<!-- 最大连接数 -->
		<property name="initialPoolSize" value="1"/>	<!-- 初始化大小 -->
		<property name="minPoolSize" value="1"/> 	<!-- 最小连接数 -->
		<property name="maxIdleTime" value="10"/>	<!-- 等待时间 -->
	</bean>
	
	<!-- 配置JdbcTemplate模版的处理对象,该对象如果要想使用一定要配置数据库连接 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"/>						<!-- 配置数据源 -->
	</bean>

</beans>

定义数据源的管理类
spring-transaction.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
	<!-- 进行事务管理的配置定义,必须配置PlatformTransactionManager接口子类-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/> 	<!-- 定义要管理的DataSource -->
	</bean>	
</beans>

业务层接口

package cn.mldn.mldnspring.service;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

import cn.mldn.mldnspring.cache.NewsEditCache;
import cn.mldn.mldnspring.vo.News;

@CacheConfig(cacheNames="news")		// 进行该接口缓存的统一配置
public interface INewsService {
	/**
	 * 根据ID查询数据
	 * @param nid 新闻编号
	 * @return 新闻数据对象
	 */
	@Cacheable(key = "#nid", unless="#result==null")
	public News get(long nid) ;
	/**
	 * 数据更新操作
	 * @param vo 要更新的数据
	 * @return 更新后的数据
	 */
	@NewsEditCache
	public News edit(News vo) ;  
	
	/**
	 * 删除新闻数据
	 * @param nid 新闻编号
	 * @return 删除成功返回true,否则返回false
	 */
	@CacheEvict(key="#nid")
	public boolean delete(long nid) ;
}

业务层实现类
编程式事务控制写在接口实现类
在查询方法中设置只读事务

package cn.mldn.mldnspring.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import cn.mldn.mldnspring.dao.INewsDAO;
import cn.mldn.mldnspring.service.INewsService;
import cn.mldn.mldnspring.vo.News;

@Service
public class NewsServiceImpl implements INewsService {
	@Autowired
	private INewsDAO newsDAO;
	@Autowired 	// 可以注入的只是一个接口的实例化对象,但是这些对象还需要配置隔离级别、传播属性
	private PlatformTransactionManager transactionManager;
	
	@Override
	public News get(long nid) {
		News vo = null;
		// TransactionDefinition通过此类设置传播属性、隔离级别、是否为只读、超时访问
		DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
		// 设置传播属性,表示必须有一个事务启动
		transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		// 隔离级别一定要使用默认的隔离级别进行控制
		transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
		transactionDefinition.setReadOnly(true); 					// 只读操作
		// 获取事务的提交状态
		TransactionStatus transactionStatus = this.transactionManager.getTransaction(transactionDefinition);
		try {
			vo = this.newsDAO.findById(nid);
			this.transactionManager.commit(transactionStatus); 		// 提交事务
		} catch (Exception e) {
			this.transactionManager.rollback(transactionStatus); 	// 回滚到指定的提交点
		}
		return vo;
	}

	@Override
	public News edit(News vo) {
		if (this.newsDAO.doUpdate(vo)) {
			return vo;
		}
		return null;
	}

	@Override
	public boolean delete(long nid) {
		boolean flag = false;
		// TransactionDefinition通过此类设置传播属性、隔离级别、是否为只读、超时访问
		DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
		// 设置传播属性,表示必须有一个事务启动
		transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		// 隔离级别一定要使用默认的隔离级别进行控制
		transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
		// 获取事务的提交状态
		TransactionStatus transactionStatus = this.transactionManager.getTransaction(transactionDefinition);
		try {
			flag = this.newsDAO.doRemove(nid);
			this.transactionManager.commit(transactionStatus); // 提交事务
		} catch (Exception e) {
			e.printStackTrace();
			this.transactionManager.rollback(transactionStatus); // 回滚到指定的提交点
		}
		return flag;
	}
}
事务注解

注解的事务控制写在业务层接口
加事务注解的接口

package cn.mldn.mldnspring.service;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.mldn.mldnspring.cache.NewsEditCache;
import cn.mldn.mldnspring.vo.News;

@CacheConfig(cacheNames="news")		// 进行该接口缓存的统一配置
public interface INewsService {
	/**
	 * 根据ID查询数据
	 * @param nid 新闻编号
	 * @return 新闻数据对象
	 */
	@Cacheable(key = "#nid", unless="#result==null")
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public News get(long nid) ;
	/**
	 * 数据更新操作
	 * @param vo 要更新的数据
	 * @return 更新后的数据
	 */
	@NewsEditCache
	@Transactional(propagation=Propagation.REQUIRED)
	public News edit(News vo) ;  
	
	/**
	 * 删除新闻数据
	 * @param nid 新闻编号
	 * @return 删除成功返回true,否则返回false
	 */
	@CacheEvict(key="#nid")
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean delete(long nid) ;
}

接口实现类

package cn.mldn.mldnspring.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.mldn.mldnspring.dao.INewsDAO;
import cn.mldn.mldnspring.service.INewsService;
import cn.mldn.mldnspring.vo.News;

@Service
public class NewsServiceImpl implements INewsService {
	@Autowired
	private INewsDAO newsDAO;
	@Override
	public News get(long nid) {
		return this.newsDAO.findById(nid);
	}
	@Override
	public News edit(News vo) {
		if (this.newsDAO.doUpdate(vo)) {
			return vo;
		}
		return null;
	}
	@Override
	public boolean delete(long nid) {
		return this.newsDAO.doRemove(nid);
	}
}

声明式事务控制
spring-transaction.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: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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-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">
	<!-- 进行事务管理的配置定义,必须配置PlatformTransactionManager接口子类-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/> 	<!-- 定义要管理的DataSource -->
	</bean>	
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- 事务控制专门提供有切面程序类 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>	<!-- 配置事务控制属性,事务控制是以业务层的方法为主的,方法名称按照统一标准定义 -->
			<tx:method name="add*" propagation="REQUIRED"/>		<!-- 设置了事务传播属性 -->
			<tx:method name="delete*" propagation="REQUIRED" />	<!-- 设置了事务传播属性 -->
			<tx:method name="edit*" propagation="REQUIRED"/>	<!-- 设置了事务传播属性 -->
			<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<!-- 定义事务要控制的切面表达式,即:在此切面范围内定义的业务方法事务控制生效  -->
		<aop:pointcut expression="execution(public * cn.mldn..service..*.*(..))" id="myPointcut"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
	</aop:config>
	
</beans>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值