您的位置:首页 > 编程语言 > Java开发

Spring 知识点总结 之 事务管理

2017-03-15 18:58 399 查看

Spring的事务管理

事务

逻辑上的一组操作,要不全部成功,要不全部失败。

原子性

隔离性

一致性

几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致

持久性

在没有事务导致的问题

读问题

脏读

读到了未提交的数据

虚读

读到了其他事务提交的数据,导致两次查询结果集数量不同

不可重复读

读到了其他事务提交的数据,导致统一条记录,两次查询结果不同

写问题

丢失更新

解决方法

读问题 通过设置事务的隔离级别解决。

写问题 通过乐观锁、悲观锁解决。

Spring的事务管理的API

PlatformTransactionManager 事务管理器

TransactionDefinition 事务隔离级别、传播策略

TransactionStatus 事务状态

关系:平台事务管理器真正管理事务对象.根据事务定义的信息TransactionDefinition.进行事务管理.在管理事务中产生一些状态.将状态记录到TransactionStatus中.

事务管理器常见的实现类(与使用的数据库连接池有关)

DataSourceTrsansactionManager (Spring JDBC 或 Mybatis)

HibernateTransactionManager (Hibernate)

JpaTransactionManager (JPA)



顶层接口方法

getTransaction(TransactionDefinition)

commit(TransactionStatus)

rollback(TransactionStatus)

事务定义

// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available

package org.springframework.transaction;

public interface TransactionDefinition {
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
int TIMEOUT_DEFAULT = -1;

int getPropagationBehavior();

int getIsolationLevel();

int getTimeout();

boolean isReadOnly();

java.lang.String getName();
}


ISOLATION_* :事务隔离级别

ISOLATION_DEFAUTL :

ISOLATION_READ_UNCOMMITTED

ISOLATION_READ_COMMITTED

ISOLATION_REPEATABLE_READ

ISOLATION_SERIALIZABLE

PROPAGATION_*: 事务传播行为:A、B为使用 同一个数据库连接的方法。

PROPAGATION_REQUIRED :A中有事务,使用A中的事务.如果没有B就会开启一个新的事务,将A包含进来.(保证A,B在一个事务中)

PROPAGATION_SUPPORTS :A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.

PROPAGATION_MANDATORY :A中有事务,使用A中的事务.如果A没有事务.抛出异常.

PROPAGATION_REQUIRES_NEW :A中有事务,将A中的事务挂起.创建一个新的事务.(保证A,B没有在一个事务中)

PROPAGATION_NOT_SUPPORTED :A中有事务,将A中的事务挂起.

PROPAGATION_NEVER :A中有事务,抛出异常.

PROPAGATION_NESTED :嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)

TransactionStatus 事务的状态

boolean isNewTransaction();
boolean hasSavepoint();
void setRollbackOnly();
boolean isRollbackOnly();
void flush();
boolean isCompleted();


Spring 事务配置(编程式事务)

不做赘述,了解即可(很少使用)

Spring为了简化事务管理的代码:提供了模板类.TransactionTemplate.

步骤一:配置一个事务管理器.
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

步骤二:配置事务管理的模板:
<!-- 配置事务管理的模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>

步骤三:在需要进行事务管理的类中,注入事务管理的模板.
<!-- 配置业务层的类 -->
<bean id="accountService" class="com.itheima.spring.demo1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
<!-- 注入事务管理的模板 -->
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>

步骤四:在业务层使用模板管理事务:
@Override
public void transfer(final String out, final String in, final Double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
accountDao.outMoney(out, money);
int d = 1 / 0;
accountDao.inMoney(in, money);
}
});
}


Spring 事务配置 (声明式事务 使用AOP实现)

Spring 通过ProxyFactoryBean 实现自动代理

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置生成代理:增强业务层类 -->
<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置目标类 -->
<property name="target" ref="accountService"/>
<!-- 注入事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 配置事务的相关属性 -->
<property name="transactionAttributes">
<!-- prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception -->
<props>
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>


通过 AspectJ 实现代理(重点掌握)

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
propagation :传播行为
isolation   :隔离级别
read-only   :是否只读
timeout     :超时信息
rollback-for:发生哪些异常回滚.
no-rollback-for:发生哪些异常不回滚.
-->
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

<!-- 配置AOP切面产生代理 -->
<aop:config>
<aop:pointcut expression="execution(* com.itheima.spring.demo3.AccountService+.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: