spring事务管理-Transaction模板(了解)

那就迫切的需要事务来进行管理了,给大家演示在Spring中,要给咱们Service加事务,怎么加,

现在是不是还没有加事务的,现在没有加事务,怎么加,我们要演示三种方式,三种方式 演示完,

Spring管理事务方式,这三种方式分别是,编码式,其中编码式我要把它标成是,绿色,这个编码式你可以

理解为观光代码,以后咱们不会用的,然后就是xml的配置式,括号aop,还有 一个是注解配置,也是属于AOP的,

紫色,明白是啥意思不,这个绿色话看着好玩,紫色是你们未来,以后都是这种紫色的这种方式,就这样了,这是

你们的final版,这是final版的,先来看轻松地,没用的编码式,顾名思义,你得在代码里编写事务,那这样缺点

在没有写你就知道,我有10个业务方法的话,我就在10个里面用事务管理的编码,先来说一下步骤,这个步骤的话

这样,他们共有的我提取到外面,准备工作第一步,别忘了刚才咱们说的,事务管理器,接口不行,你得说实现类,

咱们说这个是事务的核心,不管用三种方式的哪一种,都得把Manager给加上,所以这里的话,第一个,将核心事务管理器,

配置到Spring容器,第一步写完咱们就做一下,这里写一个bean,然后呢,class属性,DataSourceTransactionManager,

咱们就把DataSourceTransactionManager用进来,然后前面给他来一个名字,name等于transactionManager,这个

transactionManager是Spring操作事务的核心,那你说他有没有依赖呢,他依赖是谁,能想到吗,事务的操作,依赖谁,

还要问吗,你直接就能够想到的,这个哥们显然是依赖谁,是不是dataSource,为啥依赖dataSource,那咱们刚才说了

半天,操作事务,你怎么打开,connection.setAutoCommit,false,提交你事务咋提交,connection.commit,那这个哥们

负责调这些方法,手头得有connection,是不是这个意思,那connection从哪里来,是不是连接池来的,知道啥意思,

依赖关系就是这样,知道啥意思不,你说你要去花钱,那我问你依赖啥,钱,是不是依赖钱,连接池,操作咱们事务的操作,

那你操作事务,是不是得有连接事务的操作,没连接你封装什么,知道啥意思,所以他依赖于dataSource,这理解啥意思不,

所以这东西,事务的核心管理器,然后这里面封装了所有事务操作,依赖于咱们的连接池,有了核心事务管理器之后,

那咱们编码式操作事务,需要使用一个事务模板对象,这个模板对象是直接配上的,事务模板对象,name,class,

TransactionTemplate,这个咱们复制,这个transactionTemplate,这个是事务模块,这jdbc模板道理一样,他把事务

操作给你封装进去了,那就是你要想控制事务的话,一会在咱们的service里面,需要调事务的这个方法,你可以把事务

加进去,那事务模板也有依赖关系,它依赖于谁,这里只是调方法,所以他是需要transactionManager的,ref等于

transactionManager,这样的话事务模板有了,那编码式的事务,把tt属性注入进来,ref叫做transactionTemplate,

这个注入进来,然后接下来在service当中,写代码就是tt点,调用它的execute方法,然后这个execute方法,需要你

传入一个接口,TransactionCallback,那这个TransactionCallback我看一下,他的子类叫做

TransactionCallbackWithoutResult,这个TransactionTemplate,它是把事务打开和关闭的调用,

给你封装好了,然后你只需要告诉他,你打算把什么操作纳入到事务管理当中就可以了,模板他已经封装好了,

什么时候打开事务,什么时候关闭事务,什么时候回滚事务,

你只需要告诉模板,你需要干嘛就可以了,那你怎么告诉模板你需要干啥呢,就是实现这个接口,然后这里面有

这个方法,当然这里匿名内部类访问外部的需要加final,我写一个伪代码,execute方法大概就是长这样的,

首先它第一步打开,打开花事务,然后第二步调用这个方法,执行你传进去的代码,接下来第三步,提交事务,

然后你这个方法有异常的话,调你这个方法的时候会加一个try catch,如果出异常的话,它会把你这个事务进行回滚,

知道啥意思不,所以说白了,打开事务和提交事务代码已经封装好了,这样的话你代码就在事务环境内了,

看明白啥意思不,啥叫模板,就是这些代码是固定的,那这样的话事务就已经加完了,就这么简单,是不是可以执行

一下了,咱们把数据库复位,现在转100块钱,现在没有异常,先看没有异常执行成不成功,是不是没有问题,是不是

900和1100,接下来咱们造一个异常,看模板好不好使,造异常是不是把1除以0打开,这回再到Demo这儿,再运行这个

方法,这个方法肯定报错,是不是by zero,除0,那主要是看事务的问题,如果还是900和1100就对了,是这个效果,

这样就是通过编码式来控制事务,说了这是一个观光代码,因为这样的话你想,如果方法有10个,你这个execute要

调10次,虽然你不用手写打开关闭事务的代码了,但是跟以前一样,每一个业务方法里面都调这个方法,是不是麻烦,

所以这是咱们的观光代码
<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xmlns="http://www.springframework.org/schema/beans" 
		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.2.xsd 
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-4.2.xsd ">

<!-- 指定spring读取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties"  />

<!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>

<!-- 事务模板对象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
	<property name="transactionManager" ref="transactionManager" ></property>
</bean>

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


<!-- 2.Dao-->
<bean name="accountDao" class="com.learn.dao.AccountDaoImpl" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.Service-->
<bean name="accountService" class="com.learn.service.AccountServiceImpl" >
	<property name="ad" ref="accountDao" ></property>
	<property name="tt" ref="transactionTemplate" ></property>
</bean>  
	

</beans>
package com.learn.dao;

public interface AccountDao {
	
	//加钱
	void increaseMoney(Integer id,Double money);
	//减钱
	void decreaseMoney(Integer id,Double money);
}
package com.learn.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao  {

	@Override
	public void increaseMoney(Integer id, Double money) {
		
		getJdbcTemplate().update("update t_account set money = money+? where id = ? ", money,id);
		
	}

	@Override
	public void decreaseMoney(Integer id, Double money) {

		getJdbcTemplate().update("update t_account set money = money-? where id = ? ", money,id);
	}

}
package com.learn.service;

public interface AccountService {
	
	//转账方法
	void transfer(Integer from,Integer to,Double money);
	
}
package com.learn.service;

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

import com.learn.dao.AccountDao;

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {

	private AccountDao ad ;
	
	private TransactionTemplate tt;

		
	@Override
	public void transfer(final Integer from,final Integer to,final Double money) {
		
		tt.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				//减钱
				ad.decreaseMoney(from, money);
				int i = 1/0;
				//加钱
				ad.increaseMoney(to, money);
			}
		});
		
		// 1.打开事务
		// 2.调用doInTransactionWithoutResult方法
		// 3.提交事务
		
		
	}
	
		

	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	public void setTt(TransactionTemplate tt) {
		this.tt = tt;
	}

}
package com.learn.tx;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.learn.service.AccountService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
	@Resource(name="accountService")
	private AccountService as;
	
	@Test
	public void fun1(){
		
		as.transfer(1, 2, 100d);
		
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值