文章目录
1 基本知识
1.1 什么是事务
作为整体的sql语句的集合,集合内所有的语句执行一致,要么都成功,要么都失败。
1.2 什么时候使用事务
java代码中事务应该放在Service类的业务方法上。因为业务方法会调用多个dao方法,执行多个sql语句。
1.3 JDBC或者Mybatis怎么处理事务
jdbc:Connection conn; conn.commit(); conn.rollback();
mybatis: SqlSession.commit(); SqlSession.rollback();
hibernate: Session.commit();Session.rollback();
1.4 1.3中事务的处理方式有什么不足
(1) 不同的数据库访问技术,处理事务的对象和方法不同。需要了解不同数据库访问技术中使用事务的原理。掌握多种数据库事务处理逻辑,什么时候提交,什么时候回滚。
1.5 怎么解决不足
Spring提供一种处理事务的统一模型。
1.6 处理事务需要怎么做,做什么
1.6.1 事务管理器
把事务要使用的信息提供给spring就可以了。
(1)事务管理器对象,进行事务提交(commit)和事务回滚(roolback)等。
接口:PlatformTransactionManager
实现类: Spring把每一种数据库访问技术对应的事务处理类都创建好了。
mybatis访问数据库——Spring创建好的是DataSourceTransactionManager
Hibernate访问数据库——Spring创建好的是HibernateTransactionManager
<bean id="xxx", class = ".....DataSourceTransactionManager">
1.6.2 事务类型
(2) 业务方法需要什么事务?需要指定事务的类型。
《1》 事务的隔离级别
高并发情况下的对数据库数据安全性的一个控制。
《2》 事务的超时时间
如果事务超时,就直接回滚。
单位是s,默认-1,表示没有超时时间。
一般直接使用默认的。因为超时时间不好估计。
《3》事务的传播行为
控制方法是不是有事务的,是什么样子的事务的。
required: 指定的方法必须在事务内执行。若当前存在事务,就加入到当前事务中;若当前没有事务,则创建一个新事务。是spring默认的事务传播行为。
有事务的情况:
doSome() {
beginTransaction-TS
doOther(){
就在TS事务下运行
}
endTransaction-TS
}
无事务的情况:
doSome() {
doOther(){
beginTransaction-TO
就在TO事务下运行
endTransaction-TO
}
}
support: 指定的方法支持当前事务,如果当前没有事务,也可以非事务方式运行。 例如查询操作,查询操作在有没有事务的情况下都是可以执行的。
有事务的情况:
doSome() {
beginTransaction-TS
doOther(){
就在TS事务下运行
}
endTransaction-TS
}
无事务的情况:
doSome() {
doOther(){
就在没有事务的环境下运行
}
}
requires_new: 总是新建一个事务。若当前存在事务,则将当前事务挂起,直到新事务执行完毕。
doSome() {
beginTransaction-TS
doOther(){
将TS事务挂起。
beginTransaction-To
endTransaction-To
}
endTransaction-TS
}
无事务的情况:
doSome() {
doOther(){
beginTransaction-TO
就在TO事务下运行
endTransaction-TO
}
}
1.6.1 事务提交和回滚的时机
(3) 事务提交和回滚的时机
<1> 业务方法执行成功,没有异常抛出,方法执行完毕的时候提交事务。事务管理器commit
<2> 业务方法抛出运行时异常或Error,进行回滚。事务管理器rollback
运行时异常的定义:RuntimeException及其子类都属于运行时异常,例如NullPointException、NumberFormatException等。
<3> 业务方法抛出非运行时异常,主要是受查异常时,提交事务。(这个默认的是提交事务的)
受查异常:在写代码过程中,必须处理的异常。例如:IOException,SQLException等。
1.7 小结
- 管理事务的是事务管理器和它的实现类
- spring事务是一个统一的模型
1) 指定要使用的事务管理器实现类,使用
2) 指定哪些类,哪些方法需要加入事务的功能。
3) 指定方法需要的隔离级别,传播行为和超时等。
2 Spring中的事务处理方案
2.1 注解方案
适合中小项目使用。
Spring框架使用AOP实现给业务方法增加事务的功能。使用@Transactional
注解增加事务。
@Transactional
注解 需要放在public方法的上面
2.1.1 使用@Transactional注解的步骤
(1) 需要声明事务管理器对象
<bena id = "transactionManager" class = "DataSourceTransactionManager">
<property name = "dataSource" ref = "myDataSource">
</bean>
(2) 开启事务注解驱动
<tx:annotation-driven transaction-manager = "transactionManager">
(3) public方法上面加注解
@Transactional
注解 需要放在public方法的上面
@Transational(
propagation =
isolation =
readOnly = false,
rollbackFor = {NullPointerException.class, NotEnoughException.class}
)
public void buy(int goodId, int nums) {
}
rollbackFor的工作原理:
(1) rollBackFor属性值中的异常全部无条件回滚。
(2) 不在属性值中的异常,如果是RunTimeException,回滚。
2.2 AspectJ配置方案
在配置文件中声明类或者方法需要的事务。
业务方法和事务配置完全分离。
2.1.1 使用步骤
都是在xml配置文件中实现
(1) 加入AspectJ maven依赖
(2) 需要声明事务管理器对象
<bena id = "transactionManager" class = "DataSourceTransactionManager">
<property name = "dataSource" ref = "myDataSource">
</bean>
(3)声明方法需要的事务类型
配置方法的事务属性。【隔离级别,传播行为和超时】
name: 方法名称,可以使用通配符,不需要带有类名和报名
rollback-for : 需要指定全限定类名。
<tx:advice id = "myAdvice" transaction-manager = "transactionManager">
<tx:attributes>
<tx:method name = "" propagation = "" isolation = "" rollback-for = "">
<tx:method name = "">
</tx:attributes>
</tx:advice>
(4) 配置AOP
指定哪些类需要创建代理
<aop:config>
<aop:pointcut id = "" expression = "execution(* *..service..*.*(..))">
<!-- 配置增强器: 通知和切入点表达式关联起来了 -->
<aop:advisor advice-ref = "myAdvice" pointcut-ref = "servicePt">
</aop:config>