白话Spring(基础篇)---编程式事务(1)

[一知半解,就是给自己挖坑]

本文,我们来介绍一下Spring中的事务管理,在基础片中,我们直接介绍基本概念及用法,更多内容将会在高级篇中叙述,敬请期待!

-------------------------------------------------------------------------------------------------------------------------------------

1.什么是事务?

这里的事务的概念,最好在计算机环境下来理解。在操作系统中,我们为了保证一段程序执行过程不被中断,而引入了互斥锁的概念。这里事务的概念可以看作是对于互斥锁的事件过程的另一种解释。即,一个事务执行的前后,数据资源的状态始终是正确的。由此,我们得到了事务的几个基本属性:原子性,一致性,隔离性,持久性。

1.1.原子性:

原子性要求事务所包含的全部操作是一个不可分割的整体,这些操作要么全部提交成功,要么只要其中一个操作失败,那么全部失败。

1.2.一致性:

一致性要求事务再执行之前数据资源是保持一致的,在执行之后数据资源仍然保持一致。举个例子来理解:A,B两个变量之和是10为大前提,那个对其中一个变量改变值之后的结果,必须也要满足这个大前提。生活中常见的例子是银行里的转账操作就是一致性的非常好的例子。

1.3.隔离性:

隔离性即规定了不同事务之间的相互影响程度,换句话说就是不同事务之间的执行时机。这里的隔离性就衍生出原子性,一致性的概念。当一个事务开始执行对数据资源的访问时,另一个事务合适能够访问数据资源就决定了隔离性的大小。这里分为4个级别,由宽松到严格的顺序为:Read Uncommitted”,“Read Committed”,“Repeatable Read”和“Serializable”关于这4个的概念,请读者自行查阅相关资料学习。

1.4.持久性

持久性要求事务对于数据资源的操作不可逆转,即事务完成之后,程序执行流已经彻底的退出该事务,该事务对应的程序执行流不可回退。通俗点的讲,就是“不要赖账”

-------------------------------------------------------------------------------------------------------------------------------------

接下来,我们就来看看Spring中的事务管理的使用。

本文我们先来介绍Spring中的第一种方式:使用“编程式事务管理”的实现方法

准备工作:

a.操作系统:win7 x64

b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12,mybatis

c.建立Spring10,工程基本结构如下图:


-------------------------------------------------------------------------------------------------------------------------------------

1.创建BankDao.java。具体内容如下:

package com.java.ingo.dao;

import com.java.ingo.entity.Account;

/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月6日上午9:21:05
*类说明
*/
public interface BankDao {
	public void  update(Account account);
}
2.创建Account.java文件,具体内容如下:

package com.java.ingo.entity;
/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月6日上午10:36:57
*类说明
*/
public class Account {
	private int id;
	private int money;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	public Account(int id, int money) {
		super();
		this.id = id;
		this.money = money;
	}
	public Account() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}
3.创建IBankService.java文件,具体内容如下:

package com.java.ingo.service;

/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月6日上午9:26:22
*类说明
*/
public interface IBankService {
	public void transferMoney(int sourceId,int desId,int money);
}

4.创建BankServiceImpl.java文件,具体内容如下:

package com.java.ingo.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.java.ingo.dao.BankDao;
import com.java.ingo.entity.Account;
import com.java.ingo.service.IBankService;

/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月6日上午9:26:22
*类说明
*/
@Service
public class BankServiceImpl implements IBankService{
	@Autowired
	private BankDao bankDao;
	
	
	private TransactionTemplate transactionTemplate;
	
	public void setBankDao(BankDao bankDao) {
		this.bankDao = bankDao;
	}
	

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}


	public void transferMoney(final int countA,final int countB,final int money) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				Account accountA = new Account(countA,money);
				Account accountB = new Account(countB,money);
				bankDao.updateOut(accountA);
				//System.out.println(1/0);
				bankDao.updateIn(accountB);
			}
		});
	}

}
5.创建beans.xml文件,具体内容如下;

<?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:context="http://www.springframework.org/schema/context"    
    xmlns:jee="http://www.springframework.org/schema/jee"    
    xmlns:tx="http://www.springframework.org/schema/tx"    
    xsi:schemaLocation="      
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd    
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd    
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd    
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd    
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">  
	<context:component-scan base-package="com.java" />
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/db_bank" />
		<property name="username" value="root" />
		<property name="password" value="1234" />
	</bean>
	<!-- 配置mybatis的sqlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- 自动扫描mappers.xml文件 -->
		<property name="mapperLocations" value="classpath:mappers/*.xml"></property>
	</bean>
	<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.java.ingo.dao" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>
	<!-- jdbc事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>


	<bean id="transactionTemplate"
		class="org.springframework.transaction.support.TransactionTemplate">
		<constructor-arg
			type="org.springframework.transaction.PlatformTransactionManager"
			ref="transactionManager" />
	</bean>


	<bean id="namedParameterJdbcTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource"></constructor-arg>
	</bean>


	<bean id="bankService" class="com.java.ingo.service.impl.BankServiceImpl">
		<property name="transactionTemplate" ref="transactionTemplate"></property>
	</bean>

</beans>

6.创建BankMapper.xml文件,具体内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.java.ingo.dao.BankDao">  
    <update id="updateIn" parameterType="com.java.ingo.entity.Account">  
       UPDATE account SET money=money+#{money} WHERE id=#{id}
    </update>
    <update id="updateOut" parameterType="com.java.ingo.entity.Account">  
       UPDATE account SET money=money-#{money} WHERE id=#{id}
    </update>  
</mapper>   
7.创建T.java文件,具体内容如下:

package Main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.java.ingo.service.IBankService;


/**
 * @author 作者 E-mail:ingo
 * @version 创建时间:2016年3月4日上午11:46:52 类说明
 */
public class T {
	
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
		IBankService bankService = (IBankService) context.getBean("bankService");
		bankService.transferMoney(1,2,200);
	}
}
8.创建数据库db_bank,创建t_account表。



9.测试方法:运行main方法,然后刷新数据库,观察数据库变化。



10.打开System.out.println(1/0);注释,再次运行main方法,观察数据库变化。

-----------------------------------------------------------------------------------------------------------------------------------

至此,白话Spring(基础篇)---编程式事务(1)结束。


参考资料:

Spring官网:http://spring.io/docs

Mybatis官方文档:官方文档
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值