JavaEE——Spring学习笔记01【Ioc开发的模式】
JavaEE——Spring学习笔记02【Spring和Mybatis的整合】
JavaEE——Spring学习笔记04【Spring的事务管理】
目录
6.1 平台事务管理器Platform Transaction Manager
6.2 事务的定义信息TransactionDefinition
六、Spring的事务管理(内置了AOP)
在汇款业务中出现了异常,如果不考虑十五管理,会导致汇款人的资金流失,收款人收取步到汇款人的打过来的资金。我们在程序中需要紧密设计,利用Spring的十五管理机制来解决业务层中方出现的事务的问题。
1. 什么是事务
数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
数据库事务是一系列的操作,要么全部成功,要么全部失败。
2. 事务的4个特性(面试题)
2.1 原子性
事务不可分割,要么都做,要么都不做。
2.2 一致性
事务必须是使数据库从一个正确的状态变到另一个正确的状态(事务执行的前后数据要保持一致)
2.3 隔离性
一个事务的执行不能被其他事务干扰。
2.4 持久性
事务在执行结束以后,数据会得到永久保存。
3. 事务并发带来的问题
并发:同时发生
3.1 脏读
脏读是指事务A读到事务B中还没有提交的数据。
3.2 幻读(虚读)
幻读是指一个事务里面的操作发现了未被操作的数据。
3.2 不可重复
一个事务中读取了两次某个数据,读出来的数据不一致。
4. 解决读的问题
设置事务的隔离级别
4.1 Read uncommitted:未提交读
任何读的问题都不能解决
4.2 Read committed:已提交读
解决了脏读,但是不可重复读和虚读也有可能发生。
4.3 Repeatable read:重复读
解决了不可重复读,但是幻读有可能存在
4.4 Serializable:序列化读
解决所有读的问题
5. 事务的7种传播行为
5.1 保证多个操作在同一个事务中
5.1.1 PROPAGATION_REQUIRED
默认的传播行为,如果A中有事务,使用A中的事务,如果A中没有事务,会创建一个新的事务,将操作包含进来。
5.1.2 PROPAGATION_SUPPORTS
支持事务,如果A中有事务,使用A中的事务,如果A中没有事务,就不使用事务。
5.1.3 PROPAGATION_MANDATORY
如果A中有事务,使用A中事务,如果A中没有事务就抛异常。
5.2 保证多个操作不在同一个事务中
5.2.1 PROPAGATION_REQUIRES_NEW
如果A中有事务,将A中的事务挂起,创建新的事务,只包含自身的操作,如果A中没有事务,创建一个新的事务,包含自身操作!
5.2.2 PROPAGATION_NOT_SUPPORTED
如果A中有事务,将A中事务挂起,不使用事务。
5.2.3 PROPAGATION_NEVER
如果A中有事务就报异
5.3 嵌套式事务
5.3.1 PROPAGATION_NESTED
嵌套事务,如果A中有十五,按照A中事务执行,执行完成后,会设置一个保存点,执行B中的而操作,如果没有异执行通过,如果有异常,可以选择回滚到最初位置,也可以回滚到这个保存点。
6. Spring事务管理的API
6.1 平台事务管理器Platform Transaction Manager
平台事务管理器 它是一个接口,是Spring用于管理事务别的真正的对象
1.DataSourceTransactionManager:底层是JDK管理事务的
2.HibernateTransactionManager:底层是使用Hibernate管理事务
6.2 事务的定义信息TransactionDefinition
事务的定义:用于定义事务相关的信息,隔离级别、传播行为,是否可读等。
6.3 事务的状态TransactionStatus
事务的状态:用于记录事务管理过程中,事务的状态对象
6.4 事务管理的API管理
Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务管理,在事务管理过程中,产生各种状态,将这些状态信息记录到事务状态的对象中。
7. Spring事务的配置(业务层)
7.1 声明式事务管理(xml方式)
通过Spring的AOP实现的xml方式
1)更新pom.xml文件
-- 添加AspectJ的包
-- 添加Cglib的包
2)配置平台事务管理器(引入数据源)
3)配置是事务的传播行为和隔离级别及切入点
<?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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--<import resource="classpath:spring/applicationContext-dao.xml"/>-->
<!--配置平台事务的管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务的隔离级别和传播行为-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!--事务管理器和切入点配置-->
<aop:config>
<aop:pointcut id="txService" expression="execution(* com.bjpowernode.service.*.*(..))"/>
<!--事务使用内置的切面-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txService"/>
</aop:config>
</beans>
7.2 注解式事务管理
1)配置平台事务管理器
2)配置事务的驱动
<?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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<!--配置平台事务的管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务注解的驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
3)业务类中使用事务注解
/**
* Service层:业务的方法的接口实现类
*/
@Service
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService {
/*注入dao层对象*/
@Autowired
private AccountMapper accountMapper;
/**
* 实现查询所有账户信息的方法
* @return
*/
@Override
public List<Account> findAllAccounts() {
return accountMapper.selectAllAccounts();
}
/**
* 实现通过名称查询账户信息列表的业务方法
* @param name
* @return
*/
@Override
public List<Account> findAccountsByName(String name) {
return accountMapper.selectAccountsByName(name);
}
/**
* 实现添加一个账户信息的业务方法
* @param account
*/
@Override
public void addAccount(Account account) {
accountMapper.insertAccount(account);
}
/**
* 实现根据账户的id删除账户信息的业务方法
* @param id
*/
@Override
public void deleteAccount(Integer id) {
accountMapper.deleteAccount(id);
}
/**
* 实现转账功能的业务方法
* @param fromName:汇款人
* @param toName:收款人
* @param money:交易的金额
*/
@Override
public void transfer(String fromName, String toName, Integer money) {
accountMapper.outMoney(fromName, money);
/*故意设置异常*/
int num = 100/0;
accountMapper.inMoney(toName, money);
}
}
7.3 编程式事务管理
直接将事务管理放在业务代码中,不提倡大家使用
1)创建平台事务管理器:注入数据源
2)构建一个事务的模板:注入平台事务管理器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1、配置平台事务的管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2、配置事务模板:注入平台事务管理器-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
</beans>
3)在业务层代码中注入事务的模板对象
/**
* Service层:业务的方法的接口实现类
*/
@Service
public class AccountServiceImpl implements AccountService {
/*注入dao层对象*/
@Autowired
private AccountMapper accountMapper;
/*注入事务的模板*/
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 实现查询所有账户信息的方法
* @return
*/
@Override
public List<Account> findAllAccounts() {
return accountMapper.selectAllAccounts();
}
/**
* 实现通过名称查询账户信息列表的业务方法
* @param name
* @return
*/
@Override
public List<Account> findAccountsByName(String name) {
return accountMapper.selectAccountsByName(name);
}
/**
* 实现添加一个账户信息的业务方法
* @param account
*/
@Override
public void addAccount(Account account) {
accountMapper.insertAccount(account);
}
/**
* 实现根据账户的id删除账户信息的业务方法
* @param id
*/
@Override
public void deleteAccount(Integer id) {
accountMapper.deleteAccount(id);
}
/**
* 实现转账功能的业务方法
* @param fromName:汇款人
* @param toName:收款人
* @param money:交易的金额
*/
@Override
public void transfer(String fromName, String toName, Integer money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
accountMapper.outMoney(fromName, money);
/*故意设置异常*/
int num = 100/0;
accountMapper.inMoney(toName, money);
}
});
}
}
8.Spring的总结
8.1 Spring的Ioc
Ioc为Spring框架中控制反转的意思,其核心就是通过DI依赖注入将对象的创建和管理权交给Spring容器进行操作。分为两种开发模式,一种是xml开发,一种是注解开发。
Xml开发:使用bean标签进行对象的管理
注解开发:在Spring容器中配置注解的包扫描器
8.2 Spring的AOP
给业务方法进行功能增强,底层是由动态代理实现,分为JDK动态代理和Cglib动态代理。
- 切面:辅助类
- 被切面:目标类
- 连接点:目标类中的业务方法
- 切入点:目标类真正被增强的方法
- 通知:前置,后置,环绕,异常,最终
- 织入:
事务管理器的应用
- 声明式事务:配置平台事务管理器,配置传播行为和隔离级别,配置切面与切点
- 注解式事务:配置平台事务管理器,配置注解事务的驱动
- 编程式事务:配置平台事务管理器,配置事务的模板
8.3 Spring和Mybatis的整合
1. dao层
1)表对应的实体类
2)jdbc的属性文件
3)mybatis的动态代理(接口和映射文件,主配置文件)
4)Spring处理数据库连接池和mybatis的工厂对象及mybtais动态代理的容器文件
-- 加载jdbc的属性文件
-- 配置数据库连接池技术(获取mysql的参数,获取连接池的参数)
-- 配置mybatis的工厂类对象
-- 加载数据源
-- 加载mybatis的主配置文件
-- 配置别名包扫描器
-- 配置mybatis动态代理的过程
-- 配置映射文件的包
2. service层
1)业务的接口和实现类
2)配置业务层的容器文件
-- 配置注解的包扫描器
3)置事务管理
-- 配置平台事务管理器
-- 加载数据源
-- 配置隔离级别和传播行为
-- 配置切点和切面
3. 测试