Spring框架--初探事务管理器

最近初学Spring框架,今天写一篇博客来记录我学习的事务管理器,作为第一篇博客。

        了解什么是事务?个人理解:在一个事务(工作单元)中存在多个动作,只有当所有动作都成功时,这个事务才可以成功执行;否则,只要有一个动作失败,那么整个事务就算做失败。

eg:在书店使用会员卡买一本书,书店从库存中找到存书是一个动作,会员卡扣款是一个动作,库存-1是一个动作,以上三个动作只要有一个无法完成或者无法得到预期结果,整个事务就无法进行,只有以上三个动作都成功,买书的事务才可以成功。

事务符合ACID(以下四条摘自百度百科):

原子性(Atomicity):整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。

一致性(Consistency):一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。

隔离性(Isolation):隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。

持久性(Durability):在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚


        为什么要进行事务管理?进行事务管理,保证数据的完整性和一致性。

eg:仍以之前的买一本书为例,如果查书,扣款,出库三个动作是分开的,那么如果查书,扣款都成功了,而出库时由于库存不足导致失败,而前两项动作已经完成了修改数据库,就会出现扣款了却没有拿到书的情况,这时我们数据库中的数据将无法保持一致性和完整性,因此需要将以上三个动作通过事务管理器定义为同一件事务,如此就可以防止出现此种状况。


Spring提供了三种不同的事务管理器:DataSourceTransactionManager、JtaTransactionManager、HibernateTransactionManager。眼下我只学习了DataSourceTransactionManager,其他以后再说。

首先,在Spring框架下配置事务管理器。在.xml文件创建时勾选tx,在代码<beans></beans>对标签之间加入以下代码,启动事务管理器

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

<!-- 启动事务注解配置 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

而后,在类中就可以使用@Transactional注解了,该注解可以使用在方法上,也可以使用在类名上,表示该类下的方法都是事务方法。

@Transactional拥有propagation(REQUIRED),isolation,noRollbackFor,noRollbackForClassName,readOnly(false),

rollbackFor,rollbackForClassName,timeout,transactionManager,value共10个属性,括号内为默认值。


noRollbackFor,noRollbackForClassName两个属性用于对特定异常类(特定一组异常类名),遇到时不执行回滚;

rollbackFor,rollbackForClassName两个属性用于对特定异常类(特定一组异常类名),遇到时执行回滚;

readOnly属性用于定义该事务是否为只读事务,如果定义为只读事务,将无法完成对数据库的变更操作(增删改),只能执行查询;

isolation事务的隔离级别(不懂);

timeout超时时间,以s为单位;

value可选的限定描述符,指定使用的事务管理器;

transactionManager用于多线程情况(不懂);

propagation事务的传播行为(重点,常用):

这个属性的取值是枚举org.springframework.transaction.annotation.Propagation的值

总共有{"MANDATORY","NESTED","NEVER","NOT_SUPPORTED","REQUIRED","REQUIRES_NEW","SUPPORTS"}

它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播

下面主要介绍这些取值代表的含义:

"MANDATORY":使用当前的事务,如果当前没有事务,就抛出异常。特点是要求当前调用者必须是事务。

"NESTED":如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则新建一个事务。

"NEVER":以非事务方式执行,如果当前存在事务,则抛出异常。特点是要求当调用者不能是事务。

"NOT_SUPPORTED":以非事务方式执行操作,如果当前存在事务,就把当前事务挂起(暂停)。

"REQUIRED":如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。

"REQUIRES_NEW":新建事务,如果当前存在事务,把当前事务挂起。

"SUPPORTS":支持当前事务,如果当前没有事务,就以非事务方式执行。特点是随当前

调用者(事务/不是事务)的状态发生变化。

重点介绍"REQUIRED"和"REQUIRES_NEW"两个属性

eg:仍以买书为例,这次买多本书,买多本书(事务)可以看做{买一本书(事务)+ 买一本书(事务)+...+买一本书(事务)}

在代码上实现如下

买一本书的方法

@Service
public class OneBookServiceImpl implements OneBookService {
	@Autowired                                                 //实例化
	private BookDao bookDao;
	/**
	 * 购买一本书有以下五个动作(查询或变更数据库)
	 */
	@Transactional(propagation=Propagation.REQUIRES_NEW)        //可更改的地方
	@Override
	public void buyOneBook( String account , String isbn ) {
		int price = this.bookDao.getBookPrice(isbn);		//获取书的价格
		int balance = this.bookDao.getUserBalance(account);  
		if(balance<price){                                  //查询余额是否充足
			throw new RuntimeException("余额不足,请充值");
		}
		this.bookDao.updateUserBalance(account, price);	//更新用户余额
		int stock = this.bookDao.getBookStock(isbn);
		if(stock<=0){                                        //查询库存
			throw new RuntimeException("库存不足,请补充库存");
		}
		this.bookDao.updateBookStock(isbn);        //更新库存数量
	}}
买多本书的方法

@Service
public class MoreBookServiceImpl implements MoreBookService {
	@Autowired                                       //实例化
	private OneBookService oneBookService;
	@Override
	public void buyMoreBook( String account , String[] isbns ) {
		if(isbns!=null&&isbns.length>0){           //isbns有值
			for(String isbn:isbns){
				this.oneBookService.buyOneBook(account, isbn);     //嵌套调用
			}}}}


当buyOneBook方法的事务传播方式定义为"REQUIRED"时,新建一个事务,并将多个buyOneBook事务加入到这个事务中,

类似物理上的电路串联,只有当多个buyOneBook事务都能完成时,整个事务才可以完成,否则就会发生回滚。

在例子中就会产生要么把想要购买的书全部买走,要么放弃购买所有目标书。


当buyOneBook方法的事务传播方式定义为"REQUIRES_NEW"时,新建多个事务对应每个buyOneBook事务,

类似物理上的电路并联,当多个buyOneBook事务不能都完成时,可以完成的事务都可以完成,而不能完成的事务会发生回滚。

这样在例子中,能卖的起的书都会被买下来,而不能卖下来的书将放弃购买。


以上就是我的一些浅薄的关于Spring提供的事务管理器的了解。

部分内容摘自onyas前辈的博客Spring 之注解事务 @Transactional









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值