1.事务的基本概念
事务是访问数据库的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单元。通过事务,数据库能将逻辑相关的一组操作绑定在一起,以便保持数据的完整性。
事务有4个重要特性,简称ACID。
a.原子性(Automicity,A):即事务中的所有操作要么全部执行,要么全部不执行。
b.一致性(Cousistency,C):事务执行的结果必须是使数据库从一个状态变到另一个一致状态。
c.隔离性(Isolation,I):即一个事务的执行不能被另一个事务影响。
d.持久性(Durability,D):即事务提交后将被永久保存。
在javaEE开发中,事务原本属于DAO层的范畴,但一般情况下需要将事务提升到Service层,以便能使用事务的特性来管理具体的事务。
2.spring事务管理接口(常用以下两个)
a.事务管理器接口:PlatformTranscationManger
事务管理接口主要用于完成事务的提交,回滚操作,并能够获取事务的状态信息。该接口常见的实现类有以下两个
i.DataSourceTranscationManger实现类:在通过JDBC或MyBatis进行数据持久化时使用。
ii.HibernateTransactionManger实现类:在通过Herbernate进行数据持久化时使用。
b.事务定义接口:TranscationDefinition
事务定义接口中定义了事务描述相关的3类常量以及它们的操作。
i.定义了5个事务隔离常量。
ii.定义了7个事务传播行为常量。
iii.定义了1个默认事务超时时限。
应用实例:模拟银行转账来分析没有事务管理会产生什么后果,小黑,小白原本各有账户余额3000元,小黑转账1000元给小白,但转账过程中出现了异常
项目目录结构图
需要用到的数据库与数据表
create database aaa;
use aaa;
create table alipay(
aliname varchar(60),
amount double
);
insert into alipay(aliname,amount) values ('小黑','3000');
insert into alipay(aliname,amount) values ('小白','3000');
select * from alipay;
数据表图
applicationContext.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:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/aaa" />
<property name="username" value="root" />
<property name="password" value="123abc" />
</bean>
<!-- 配置jdbcTemplate模板 注入dataSource -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置DAO,注入jdbcTemplate属性值 -->
<bean id="alipayDao" class="com.xiaochen.dao.AlipayDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
</beans>
IAlipayDao.java
package com.xiaochen.dao;
public interface IAlipayDao {
public void transfer(String fromA,String toB,int amount);
}
AlipayDaoImpl.java
package com.xiaochen.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class AlipayDaoImpl implements IAlipayDao{
//定义jdbcTemplate类型的jdbcTemplate对象属性,但并未还未实例化
//通过改属性可以更方便的操作数据库,无须再用以前JDBC的繁琐步骤
JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void transfer(String fromA, String toB, int amount) {
//执行转账操作:小黑将钱转出
String sql1="update alipay set amount=amount-? where aliname=?";
jdbcTemplate.update(sql1,amount,fromA);
//模拟转账操作时发生异常
Integer.parseInt("a");
//执行转账操作:小白接收小黑转来的钱
String sql2="update alipay set amount=amount+? where aliname=?";
jdbcTemplate.update(sql2,amount,toB);
}
}
Test.java
package com.xiaochen.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xiaochen.dao.IAlipayDao;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
IAlipayDao alipayDao=(IAlipayDao)context.getBean("alipayDao");
alipayDao.transfer("小黑", "小白", 1000);
}
}
运行结果图
转账前的数据库
转账后的数据库
可以发现:小黑的钱刚转出去时就发生了异常,程序中断,而小白却还没有收到小黑转来的钱。因此,小黑的钱就不翼而飞了。