利用简单的转账来学习spring的事务控制

一.Spring封装了事务管理操作
1.事务管理的操作:1.打开事务
2.回滚事务(操作出现异常,把数据返回)
3.提交事务(进行数据更新)
2.Spring中的操作对象
(1)不同平台,操作事务的代码各不相同.spring给我们提供了一个接口 PlatformTransactionManager
我们使用的都是接口的实现类,整合jdbc使用的DatasourceTransactionManager,整合hibernate使用的则HibernateTransitionmanager
注意的是:在spring中的事务管理,核心对象就是TransactionManager对象
(2)spring管理事务的属性介绍

事务隔离级别: 1读未提交

                            2 读已提交

                            4 可重复读

                            8 串行化

是否只读 true 只读

                         False 可操作

事务的传播行为:
在这里插入图片描述
二:Sprig管理事务方式
事务控制分为两种:

编程式事务控制
声明式事务控制
所谓编程式事务控制就是自己写方法来实现
编程式事务实现(基本不用,但是也要了解一下,):
1.将核心事务管理器配置到spring容器
在这里插入图片描述
2.配置TransactionTemplate模板
在这里插入图片描述
3.将事务模板注入到Service
在这里插入图片描述
4.在Service中调用模板
在这里插入图片描述
编码式事务控制繁琐且容易出错,所以一般使用声明式的事务管理
声明式事务管理是指在xml配置设置,一次设置,全局生效
声明式事务管理步骤:
导包
在这里插入图片描述
加约束
在这里插入图片描述

配置通知:

<?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:p="http://www.springframework.org/schema/p"
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:context="http://www.springframework.org/schema/context"
   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.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!-- 0.spring读取配置文件,配置文件写的是sqL配置,这样就可以直接改动文件,更方便 -->
<context:property-placeholder location="classpath:db.properties"/>
<!--1.配置数据连接池 -->
<bean name ="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 引入db.properties的内容 -->
<property name ="driverClass" value="${mysql.driverClass}"></property>
<property name ="jdbcUrl" value="${mysql.url}"></property>
<property name ="user" value="${mysql.username}"></property>
<property name ="password" value="${mysql.password}"></property>
</bean>
<!-- 配置AccountDaoImpl层 -->
<bean name="accountDao" class="cn.oracle.userdao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- spring编码式的事务管理 -->
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务  -->
<!--  beans: 最基本

context:读取properties配置

aop:配置aop

tx:配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
	<!-- 以方法为单位,指定方法应用事务什么属性,
	isolation:隔离级别
	 read-only:只读属性
	 propagation:传播行为
	  -->
	<!-- 增加删除等配置基本信息 -->
	<tx:method name="transform" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
	<tx:method name="add*" 		isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
	<tx:method name="find*" 	isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
	<tx:method name="get*" 		isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
	<tx:method name="save*" 	isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
	<tx:method name="persist*" 	isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
	<tx:method name="delete*" 	isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
	<tx:method name="remove*" 	isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
	<tx:method name="update*" 	isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
	
	</tx:attributes>
</tx:advice>
	<aop:config>
	<!-- 切入点表达式,不用切入点不知道用哪个方法,第一个*代表的是返回值 -->
		<aop:pointcut expression="execution(* cn.oracle.services.*.*(..))" 
		id="myPoint"/>
		<!-- 织入事务管理和切入方法 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint"/>
	</aop:config>
<!-- 配置业务层 把dao层注入-->
<bean name="accountService" class="cn.oracle.services.AccountServicesImpl">
	<property name="ad" ref="accountDao"></property>
</bean>
</beans>
实现业务
package cn.oracle.userdao;

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

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
	//转账业务逻辑
	@Override
	public void addMoney(Integer id, double money) {
		String update ="update t_user set money=money+? where id=?";
		System.out.println(super.getJdbcTemplate());
		super.getJdbcTemplate().update(update,money,id);
		//StringBuffer a=new StringBuffer();
		//a.append("sa");
	}
//减
	@Override
	public void minusMoney(Integer id, double money) {
		String update ="update t_user set money=money-? where id=?";
		super.getJdbcTemplate().update(update,money,id);
		
	}

services层

package cn.oracle.services;

import cn.oracle.userdao.AccountDao;

/*基于xml方式的aop事务的声明式管理*/


public class AccountServicesImpl implements AccountService {
	AccountDao ad;
	
	//转账,先减后加(转账人,转账目标人,转账金额)
	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	@Override
	public void transform(final Integer from, final Integer to,final  double money) {
	//调用减法和加法同时
		ad.minusMoney(from,money);
		int i= 1 / 0;
		ad.addMoney(to,money);	
	}
	

}

测试

import cn.oracle.advice.AccountServicesImpl;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServicesImplTest {
@Resource(name="accountService")
private AccountServicesImpl as;
	@Test
	public void testTransform() {
		as.transform(1, 2,100);
	
	}

}

结果

数据库
如果失败的话会自动回滚,不发生改变
二:补充说明:基于注解的实现事务控制,这种方式比较简单,但是不方便大量的services层的时候使用
基于注解的xml

<bean name ="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 引入db.properties的内容 -->
<property name ="driverClass" value="${mysql.driverClass}"></property>
<property name ="jdbcUrl" value="${mysql.url}"></property>
<property name ="user" value="${mysql.username}"></property>
<property name ="password" value="${mysql.password}"></property>
</bean>
<!-- 配置AccountDaoImpl层 -->
<bean name="accountDao" class="cn.oracle.userdao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- spring编码式的事务管理 -->
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 开启使用注解管理aop业务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- 配置业务层 把dao层注入-->
 <bean name="accountService" class="cn.oracle.advice.AccountServicesImpl">
	<property name="ad" ref="accountDao"></property>
</bean> 
</beans>

services层

public class AccountServicesImpl  {
	@Autowired
	private AccountDao ad;
	
	//转账,先减后加(转账人,转账目标人,转账金额)
	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
	public void transform(final Integer from, final Integer to,final  double money) {
	//调用减法和加法同时
		ad.minusMoney(from,money);
		//int i= 1 / 0;
		ad.addMoney(to,money);	
	}

dao层不需要修改,测试结果
在这里插入图片描述

补充一些常见错误点:
1.使用事务的话mysql数据库需要更改表类型为inndB,不然不支持,

2.dataSource属性未找到,注意看你的xml配置中是否链接上数据链接池。
暂时没有出现其他错误,出现了再改。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值