一 Spring的事务概念
1 事务概念
(1)什么是事务
事务是是数据库操作的基本单元,是指对一组的数据的操作,要么都成成功,要么都失败
(2)事务特性
- 原子性
- 一致性
- 隔离性
- 持久性
(3)不考虑隔离性产生读的问题
(4)解决读的问题
- 设置隔离级别
2 Spring事务管理两种方式
第一种 编程式事务管理(不用)
第二种 声明式事务管理
(1)基于xml配置文件实现
(2)基于注解实现
3 Spring事务管理的api介绍
接口 PlatformTransactionManager
事务管理器
(1)Spring针对不同的dao层框架,提供接口不同的实现类
-
org.springframework.jdbc.datasource.DataSourceTransactionManager
使用mybatis进行持久化数据使用 -
org.springframework.orm.hibernate5.HibernateTransactionManager
使用Hibernate5.0版本进行持久化数据使用
(2)首先配置事务管理器
二 转账环境搭建
1 正确执行
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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置数据库相关参数properties的属性:${url} -->
<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.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置orderService-->
<bean id="orderService" class="Tx.OrdersService">
<!--注入orderDao-->
<property name="ordersDao" ref="orederDao"></property>
</bean>
<!--配置orederDao-->
<bean id="orederDao" class="Tx.OrdersDao">
<!--注入jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
OrdersDao.java
package Tx;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Created by yang on 17-11-2.
*/
public class OrdersDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//减少钱
public void lessMoney(){
String sql = "update user set salary = salary - ? where id =?";
jdbcTemplate.update(sql,100,1);
}
//增加钱
public void AddMoney(){
String sql = "update user set salary = salary + ? where id =?";
jdbcTemplate.update(sql,100,2);
}
}
OrdersService.java
package Tx;
/**
* Created by yang on 17-11-2.
*/
public class OrdersService {
private OrdersDao ordersDao;
public void setOrdersDao(OrdersDao ordersDao) {
this.ordersDao = ordersDao;
}
public void money(){
ordersDao.lessMoney();
ordersDao.AddMoney();
}
}
Text.java
package Tx;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by yang on 17-11-2.
*/
public class Text {
@Test
public void text(){
ApplicationContext context = new ClassPathXmlApplicationContext("Spring/applicationContext.xml");
OrdersService ordersService = (OrdersService) context.getBean("orderService");
ordersService.money();
}
}
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/text?useUnicode=true&characterEncoding=utf-8
2 产生问题
如果杨减少100之后,出现异常,邹不会多100,钱丢了。
3 解决
添加事务解决,出现异常进行回滚操作
三 声明式事务管理(xml配置)
第一步 引入约束
<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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
第二步 配置事务管理
<!--第一步 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
第三步 配置事务增强
<!--第二步 配置事务增强-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作-->
<tx:attributes>
<!--设置进行事务操作的方法匹配规则-->
<tx:method name="money" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
第四步 配置切面
<!--第三步 配置切面-->
<aop:config>
<!--切入点-->
<aop:pointcut id="pointcut1" expression="execution(* Tx.OrdersService.*(..))"></aop:pointcut>
<!--切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"></aop:advisor>
</aop:config>
完整Tx.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置数据库相关参数properties的属性:${url} -->
<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.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--第一步 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--第二步 配置事务增强-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--做事务操作-->
<tx:attributes>
<!--设置进行事务操作的方法匹配规则-->
<tx:method name="money" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--第三步 配置切面-->
<aop:config>
<!--切入点-->
<aop:pointcut id="pointcut1" expression="execution(* Tx.OrdersService.*(..))"></aop:pointcut>
<!--切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"></aop:advisor>
</aop:config>
<!--配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置orderService-->
<bean id="orderService" class="Tx.OrdersService">
<!--注入orderDao-->
<property name="ordersDao" ref="orederDao"></property>
</bean>
<!--配置orederDao-->
<bean id="orederDao" class="Tx.OrdersDao">
<!--注入jdbcTemplate-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans>
- 增加钱出现异常,减少钱就不会执行
四 声明式事务管理(注解)
第一步 配置事务管理器
<!--第一步 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步 开启事务注解
<!--第二步 开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
第三步 在要使用事务的方法所在类上面添加注解@Transactional
package TxAnno;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class OrdersService {
private OrdersDao ordersDao;
public void setOrdersDao(OrdersDao ordersDao) {
this.ordersDao = ordersDao;
}
public void money(){
ordersDao.lessMoney();
int a = 100/0;
ordersDao.AddMoney();
}
}