Spring学习-30:Spring中的事务管理之环境搭建

Spring的事务管理分成两类:

1、 编程式事务管理:手动编写代码完成事务管理。在实际应用中很少使用,通过TransactionTemplate手动管理事务。

2、声明式事务管理:不需要手动编写代码,配置。使用XML配置声明式事务,开发中推荐使用(代码侵入性最小),Spring的声明式事务是通过AOP实现的。

事务的讲解我们以转账案例为基本场景,下面介绍转账案例的环境准备:

(1)创建数据库表account:

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `money` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'aaa', '1000');
INSERT INTO `account` VALUES ('2', 'bbb', '1000');
INSERT INTO `account` VALUES ('3', 'ccc', '1000');

(2)创建一个web项目,导入相应的jar包(基本开发包6个、mysql驱动、C3P连接池)

(3)建立配置文件applicationContext.xml、jdbc.properties、log4j.properties

(4)新建两个接口

package com.js.demo1;

public interface AccountDao {
	/**
	 * 转出的方法
	 * @param from:转出得人
	 * @param money:转账金额
	 */
	public void out(String from,Double money);
	/**
	 * 转入的方法
	 * @param to:转入的人
	 * @param money:转账金额
	 */
	public void in(String to,double money);
}
package com.js.demo1;
/**
 * 账户的业务层的接口
 * @author JiangShuai
 *
 */
public interface AccountService {
	/**
	 * 转账的方法
	 * @param from:从哪转出
	 * @param to:转入目标
	 * @param money:转账金额
	 */
	public void transfer(String from,String to,double money);
}

(5)编写两个实现类

package com.js.demo1;

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

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
	/**
	 * 转出的方法
	 * @param from:转出得人
	 * @param money:转账金额
	 */
	public void out(String from, Double money) {
		String sql = "update account set money = money - ? where name = ?";
		this.getJdbcTemplate().update(sql,money,from);
	}
	/**
	 * 转入的方法
	 * @param to:转入的人
	 * @param money:转账金额
	 */
	public void in(String to, double money) {
		String sql = "update account set money = money + ? where name = ?";
		this.getJdbcTemplate().update(sql,money,to);
	}

}

package com.js.demo1;

public class AccountServiceImpl implements AccountService{
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	/**
	 * 转账的方法
	 * @param from:从哪转出
	 * @param to:转入目标
	 * @param money:转账金额
	 */
	public void transfer(String from, String to, double money) {
		accountDao.out(from, money);
		accountDao.in(to, money);
	}
	
}



(6)在配置文件中配置bean

<?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"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driver}"></property>
	<property name="jdbcUrl" value="${jdbc.url}"></property>
	<property name="user" value="${jdbc.user}"></property>
	<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 定义JDBC的模板类 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 业务层类 -->
<bean id="accountService" class="com.js.demo1.AccountServiceImpl">
	<property name="accountDao" ref="accountDao"></property>
</bean>
<!-- 持久层类 -->
<bean id="accountDao" class="com.js.demo1.AccountDaoImpl">
	<!-- 注入连接池对象,通过连接池对象去创建JDBC模板 -->
	<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>



至此,事务讲解部分的项目场景搭建就完成了。

下面,我们简单的测试一下这个场景的功能:

package com.js.demo1;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
	@Autowired
	@Qualifier("accountService")
	private AccountService accountService;
	@Test
	public void demo(){
		//完成转账
		accountService.transfer("aaa", "bbb", 100d);
	}
}

查看数据库:


金额改变正确,说明功能正常。

这时候,系统内不存在事务,如果在转账过程中有异常发生,会出现什么情况呢?

修改AccountServiceImpl类:

package com.js.demo1;

public class AccountServiceImpl implements AccountService{
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	/**
	 * 转账的方法
	 * @param from:从哪转出
	 * @param to:转入目标
	 * @param money:转账金额
	 */
	public void transfer(String from, String to, double money) {
		accountDao.out(from, money);
		int i = 1/0;   //制造异常
		accountDao.in(to, money);
	}
	
}

重新运行测试:


发现“aaa”的钱扣了,但是“bbb”的钱没增加。

显然,这时候就需要有事务的管理了。

具体的事务管理的两种方式,我将在下一节跟大家探讨。欢迎关注。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值