【Spring DAO】事务管理基础

Spring事务管理基础

什么是数据库事务?

数据库事务有严格定义,必须满足4个特性:原子性、一致性、隔离性、和持久性,简称ACID。简单说明如下:
原子性:表示组成事务的多个数据库操作是一个不可分割的单元,只有所有的操作执行成功,整个事务才提交,有一个失败就回滚到数据库之前的状态。
一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的。
隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,它的操作不会对对方产生干扰。
持久性:一旦事务提交成功后,事务中所有的数据库操作必须被持久化到数据库中。

数据并发问题

数据库的数据可能被多个事务访问,如果没有采取必要的隔离措施,就会导致各种并发问题,破坏数据的完整性。可以归类为以下问题:
脏读:A事务读取B事务尚未提交的更改数据,并在这个数据基础上进行操作,如果B回滚了,A事务读取到的数据是不被承认的。
不可重复读:指A事务读取了B事务已经提交更改的数据。
幻象读:A事务读取B事务提交的新增数据,将出现幻象读的问题。
第一类丢失更新:A事务撤销时,把已经提交的B事务更新数据覆盖了。
第二类丢失更新:A事务覆盖B事务已经提交的数据。

事务的隔离级别

通过一张表来看一下数据库的事务隔离级别:

基于XML配置

Spring在基于Schema的配置中,提供了tx命名空间,配合aop命名空间提供切面,业务方法的事务配置得到了大大的简化,这也是工程开发中最常用的一种方式,下面我们通过一个demo来演示一下:
假设我们的业务类为UserServiceImpl代码如下:
public class UserServiceImpl implements UserService {

	private UserDao userDao;
	
	public void addUser(User user) {
		userDao.addUser(user);
	}

	public void updateUser(User user) {
		userDao.updateUser(user);
	}

}
我们用Spring如何为这两个方法配置事务呢?利用tx事务增强和aop切面配合来完成,这是一组非常方便强大的武器。配置如下:
<?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: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.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- 配置dao和service -->
	<bean id="userDao" class="spring.dao.demo2.UserDaoImpl"></bean>
	<bean id="userService" class="spring.dao.demo2.UserServiceImpl">
		<property name="userDao" ref="userDao"></property>
	</bean>
	
	<!-- 事务管理器 -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- aop配置切面逻辑 -->
	<aop:config>
		<aop:pointcut expression="execution(* spring.dao.demo2.UserServiceImpl.*(..))" id="serviceMethod"/>
		<aop:advisor advice-ref="txAdvice"/>
	</aop:config>
	
	<!-- 事务增强 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="addUser" read-only="false"/>
			<tx:method name="updateUser" rollback-for="Exception"/>
		</tx:attributes>
	</tx:advice>
</beans>

基于注解进行配置

除Xml配置外,Spring还提供了基于注解的事务配置方式,废话不多说,我们还是通过一个demo看一下,这个怎么玩?
如果我们希望对UserServiceImpl业务类的方法进行事务管理,基于注解非常方便,代码如下:
@Transactional
public class UserServiceImpl implements UserService {

	private UserDao userDao;
	
	public void addUser(User user) {
		userDao.addUser(user);
	}

	public void updateUser(User user) {
		userDao.updateUser(user);
	}

}
对,你没有看错,只是在类上加了一行 @Transactional就可以将业务类的方法进行事务管理,不过想让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:p="http://www.springframework.org/schema/p"
	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.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- 配置dao和service -->
	<bean id="userDao" class="spring.dao.demo2.UserDaoImpl"></bean>
	<bean id="userService" class="spring.dao.demo2.UserServiceImpl">
		<property name="userDao" ref="userDao"></property>
	</bean>
	
	<!-- 事务管理器 -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 对标注@Transactional注解的业务bean进行加工,织入事务管理切面 -->
	<tx:annotation-driven transaction-manager="txManager"/>
</beans>
这样Spring就可以知道标注了@Transactional的类是需要被事务管理的。

如果@Transactional被标注在类上,类中定义的public方法进行事务管理。
如果在业务实现类方法上标注@Transactional,则会覆盖类的标注。

这个注解有几个属性需要了解:
propagation:事务传播行为
isolation:事务隔离级别
readOnly:事务读写性
timeout:超时时间,int型,以秒为单位
rollbackFor:一组异常类,遇到时进行回滚,类型为:Class<? extends Throwable>[]
rollbackForClassName:一组异常名,遇到进行回滚,类型为String[]
noRollbackFor:一组异常类,遇到不回滚,类型为:Class<? extends Throwable>[]
noRollbackForClassName:一组异常名,遇到不回滚,类型为String[]

至此,Spring的基本知识和基本配置方法讲完了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值