[一知半解,就是给自己挖坑]
本文,我们来介绍一下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官方文档:官方文档