spring的事务管理(转账环境搭建)
Spring的事务管理
事务概念
1 什么是事务
2 事务特性
3 不考虑隔离性产生读问题
4 解决读问题
(1)设置隔离级别
Spring事务管理api介绍
1 spring事务管理两种方式
第一种 编程式事务管理(不用)
第二种 声明式事务管理
(1) 基于xml配置文件实现
(2) 基于注解方式实现
2 Spring事务管理api介绍
(1)spring针对不同的dao层框架,提供接口不同的实现类。
(2)首先配置事务管理器
搭建转账环境
1 创建数据库表,添加数据
2 创建service和dao类,完成注入关系
(1)service层又叫业务逻辑层
(2) dao层,单纯对数据库操作层,在dao层不添加业务。
(3) 需求 : 小王 转账100 给小马
小王少100
小马多100
3 产生问题
(1)如果小王少了100以后,出现异常,小马不会多100,钱丢失。
4 解决
(1)添加事务解决,出现异常回滚操作。
声明式事务管理(xml)
org.springframework.jdbc.datasource.DataSourceTransactionManager
(1) 配置文件方式aop思想配置
第一步 配置事务管理器
第二步 配置事务增强
第三步 配置切面
org.springframework.jdbc.datasource.DataSourceTransactionManager
完整spring配置文件 bean3.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启c3p0连接池操作 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///news"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 第一步配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<propery name="dataSource" ref="dataSource"></propery>
</bean>
<!-- 第二步配置事务增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!-- 做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配规则 -->
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 第三步配置切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(*com.cn.service.*(..))" id="pointcut1"/>
<!-- 切面 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
<!-- 创建service和dao对象, 在service注入dao对象 -->
<bean id="ordersService" class="com.cn.service.OrdersService">
<property name="orderDao" ref="orderDao"></property>
</bean>
<bean id="orderDao" class="com.cn.dao.OrderDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
代码实例
dao层OrderDao.java
package com.cn.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class OrderDao {
//注入jdbcTemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 做对数据库操作的方法,不写业务操作
*
*/
//少钱的方法
public void lessMoney(){
String sql=" update account set salary=salary-? where username=?";
jdbcTemplate.update(sql, 100, "小王");
}
//小马多钱的方法
public void moreMoney(){
String sql=" update account set salary=salary+? where username=?";
jdbcTemplate.update(sql, 100, "小马");
}
}
Service层OrdersService.java
package com.cn.service;
import com.cn.dao.OrderDao;
public class OrdersService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
//调用dao的方法
//业务逻辑层,写转账业务
public void accountMoney(){
//小王少100
orderDao.lessMoney();
int i=1/0;
//小马多100
orderDao.moreMoney();
}
}
}
测试类TestService.java
package com.cn.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestService {
@Test
public void testDemo(){
ApplicationContext context=
new ClassPathXmlApplicationContext("bean3.xml");
OrdersService service=(OrdersService) context.getBean("ordersService");
service.accountMoney();
}
}
程序下载地址:http://pan.baidu.com/s/1i5utMlf
声明式事务管理(注解)
第一步 配置事务管理器
第二步 配置事务注解
第三步 在要使用事务的方法所在类上面添加注解
具体代码
bean3.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启c3p0连接池操作 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///news"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 第一步配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<propery name="dataSource" ref="dataSource"></propery>
</bean>
<!-- 第二步开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<!-- 创建service和dao对象, 在service注入dao对象 -->
<bean id="ordersService" class="com.cn.service.OrdersService">
<property name="orderDao" ref="orderDao"></property>
</bean>
<bean id="orderDao" class="com.cn.dao.OrderDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
</beans>
OrderDao.java
package com.cn.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class OrderDao {
//注入jdbcTemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 做对数据库操作的方法,不写业务操作
*
*/
//少钱的方法
public void lessMoney(){
String sql=" update account set salary=salary-? where username=?";
jdbcTemplate.update(sql, 100, "小王");
}
//小马多钱的方法
public void moreMoney(){
String sql=" update account set salary=salary+? where username=?";
jdbcTemplate.update(sql, 100, "小马");
}
}
OrdersService.java
package com.cn.service;
import org.springframework.transaction.annotation.Transactional;
import com.cn.dao.OrderDao;
@Transactional
public class OrdersService {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
//调用dao的方法
//业务逻辑层,写转账业务
public void accountMoney(){
//小王少100
orderDao.lessMoney();
int i=1/0;
//小马多100
orderDao.moreMoney();
}
}
测试类
package com.cn.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestService {
@Test
public void testDemo(){
ApplicationContext context=
new ClassPathXmlApplicationContext("bean3.xml");
OrdersService service=(OrdersService) context.getBean("ordersService");
service.accountMoney();
}
}