事务是企业应用中最小的逻辑执行单元
事务的特性:(ACID)
-原子性
-一致性:数据库事务提交之前和之后都是一致性
-隔离性:事务的中间状态对于外界是隔离的
-持续性:事务一旦提交,对数据库的修改将永远生效
传统事务控制的问题
持久化技术不同,做事务控制的API也会不同,事务控制代码也会随之改变
事务控制代码需要放在service层完成,但我们将service与dao分离,目的为了service只负责业务变化,DAO专门负责持久化技术的变化,事务控制代码在service层完成,持久化技术的改变,必然导致Service随之改变
sprig的事务策略
特征:spring的事务管理不需要与特定的事务API耦合(面向PlateformTransactionManager),对不同的持久层访问技术,编程式事务提供一致的事务管理,通过模块化的一致性管理事务
优势:不再需要硬编码的方式的写事务
让业务逻辑API与具体的事务逻辑分离
没有提供实际的事务支持,只是对底层事务的包装,所以能自由切换底层的事务。
策略模式:当我们的程序要完成某个功能,但实现该功能有多种策略算法,我们目前不希望或者不确定采用哪种实现算法。采用策略模式。
策略模式由几个部分组成:
1.一个策略接口,该策略接口只定义实现该功能所需的方法,不提供实现
PlateformTransactionManager就是事务控制的策略接口,只定义事务控制的三个方法,我们程序面向策略接口编程,我们程序与具体的算法分离。
2.N个策略实现类:为不同的算法提供对应的策略实现类
DataSourceTransactionManager(jdbc),HibernateTransactionManager,jpa(JPA),jta(使用jta的全局事务)Weblogicjta,WebSphereUow
3.Context类,负责为程序“智能“”地选择一个策略实现类。需要配置
ApplicationContext
transactionDefinition:代表事务定义,是指定事务相关属性
–隔离级别
–传播性
–超时(事务靠数据加锁实现)一定设置 -1永不超时
–是否只读,只读事务有更好的性能
JTA全局事务:跨数据库的操作,用于保证程序对多个数据库的修改,要么同时生效,要不同时回滚。JTA全局事务:基于两段式提交的原理,需要应用服务器Weblogic, WebSphere,Jboss
spring 的事务控制有两种方式:
-编程式事务:需要自己来写Java代码控制事务,面向PlateformTransactionManager编程,还可结合AOP
你可以自己写事务控制代码,获得绝对的控制权,但是风险很大
–声明式事务:不需要写Java代码,只要用xml或注解配置一个即可
定义一个事务
package org.fkjava.spring.aspect;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class Txaspect {
private PlatformTransactionManager transactionManager;
private Object rvt=null;
public Object tx (ProceedingJoinPoint jp)
{ DefaultTransactionDefinition td=new DefaultTransactionDefinition();
//隔离,传播,超时,只读
TransactionStatus ts=transactionManager.getTransaction(td);
try {
rvt=jp.proceed();//直接用原来的参数调用目标方法
//提交事务
transactionManager.commit(ts);
} catch (Exception e) {
transactionManager.rollback(ts);
//回滚事务
e.printStackTrace();
}
return rvt;
}
}
appCtx.xml
<bean id="transactionManager" class=" org.springframework.orm.hibernate5.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<bean id=txAspect class="org.fkjava.spring.aspect.Txaspect"
p:transactionManager-ref="transactionManager">
还有AOP的配置省略。。。
声明式事务:只要用xml和注解配置一下
spring作者已经写好了一个功能强大的切面类
,只要配置即可。
<!-- 为platformTransactionManager事务策略接口实现类-->
<bean id="transactionManager" class=" org.springframework.orm.hibernate5.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<!-- 这段代码背后隐藏了spring作者所写的一些功能非常强大的事务控制 aspect-->
<tx:advice id="txAdvice">
<!-- 下面就是用于定义事务属性 -->
<tx:attributes>
<tx:method name="get*" read-only="true" timeout="8" />
<tx:method name="*" timeout="5"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(*org.fkjava.s2sh.service.impl.*.*(..))"
id="fkpo"/>
<!-- 将制定的advice织入到切入点表达式所匹配的方法中->
<aop:advisor advice-ref="txAdvice" pointcut-ref="fkpo"/>
</aop:config>