创建业务层代码
package com.itheima.demo2;
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 转账的方法
*/
public void pay(final String out, final String in, final double money) {
// 先扣钱
accountDao.outMoney(out, money);
// 模拟异常
int a = 10/0;
// 加钱
accountDao.inMoney(in, money);
}
}
创建Dao层代码
package com.itheima.demo2;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
// JdbcDaoSupport中已经通过setDataSource方法定义了常量的JdbcTemplate对象,所有注入dataSource就行了
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
/**
* 扣钱
*/
public void outMoney(String out, double money) {
this.getJdbcTemplate().update("update t_account set money = money - ? where name = ?", money,out);
}
/**
* 加钱
*/
public void inMoney(String in, double money) {
this.getJdbcTemplate().update("update t_account set money = money + ? where name = ?", money,in);
}
}
基于XML的声明式事务
创建配置文件,在src目录下创建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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置C3P0的连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 平台事务管理器需要配置数据源才能够管理事务 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 声明式事务(采用XML配置文件的方式) -->
<!-- 先配置通知 -->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 给方法设置数据库属性(隔离级别,传播行为) -->
<!--
name :绑定事务的方法名,可以使用通配符,可以配置多个。
propagation :传播行为
isolation :隔离级别;有以下五种:
ISOLATION_DEFAULT(默认值,采用数据库的隔离级别)
ISOLATION_READ_UNCOMMITTED: 读未提交
ISOLATION_READ_COMMITTED: 读已提交(可避免脏读)
ISOLATION_REPEATABLE_READ: 可重复读(可避免脏读和不可重复读)
ISOLATION_SERIALIZABLE: 串行化(可避免脏读,不可重复读,幻读)
read-only :是否只读
timeout :超时信息
rollback-for:发生哪些异常回滚.
no-rollback-for:发生哪些异常不回滚.
-->
<tx:method name="pay" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知aop:advisor -->
<aop:config>
<!-- aop:advisor,是Spring框架提供的通知 -->
<aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.itheima.demo2.AccountServiceImpl.pay(..))"/>
</aop:config>
<!-- 配置业务层和持久层 -->
<bean id="accountService" class="com.itheima.demo2.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="com.itheima.demo2.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
基于注解的声明式事务
创建配置文件,在src目录下创建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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置C3P0的连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启事务的注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置业务层和持久层 -->
<bean id="accountService" class="com.itheima.demo3.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="com.itheima.demo3.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
在业务层上添加一个注解:@Transactional:
package com.itheima.demo3;
import org.springframework.transaction.annotation.Transactional;
/**
* Transactional类上添加了注解,类中的所有的方法全部都有事务
* @author Administrator
*/
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
/**
* 转账的方法
*/
@Transactional
public void pay(final String out, final String in, final double money) {
// 先扣钱
accountDao.outMoney(out, money);
// 模拟异常
int a = 10/0;
// 加钱
accountDao.inMoney(in, money);
}
}
事务的传播行为
- 举例说明什么是事务的传播行为:
比如说一个类中有两个方法A和B方法,这两个方法通过AOP技术都增强提交事务的功能public class Hello{ public void A(){ 张三用户减100元操作; // 调用B方法 this.B(); } public void B(){ 李四用户加100元操作 } }
事务的传播行为就是来解决这种事务(A)调用事务(B)时,被调用事务方法(B)如何进行事务管理的问题
- 共有七种解决方案(即7种传播行为)
<1> PROPAGATION_REQUIRED(默认值): A中有事务,使用A中的事务.如果没有,B就会开启一个新的事务,将A包含进来.(保证A,B在同一个事务中),默认值!!
<2> PROPAGATION_SUPPORTS: A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.
<3> PROPAGATION_MANDATORY: A中有事务,使用A中的事务.如果A没有事务.抛出异常.
<4> PROPAGATION_REQUIRES_NEW: A中有事务,将A中的事务挂起.B创建一个新的事务.(保证A,B没有在一个事务中)
<5> PROPAGATION_NOT_SUPPORTED: A中有事务,将A中的事务挂起.
<6> PROPAGATION_NEVER: A中有事务,抛出异常.
<7> PROPAGATION_NESTED: 嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)
声明:
有一些博文是看的黑马程序员视频,然后跟着老师做的笔记
Spring是跟子路老师学的
特此感谢,写这些文章的目的是为了自己方便查阅