其他分享
首页 > 其他分享> > 学习笔记--Spring的事务控制

学习笔记--Spring的事务控制

作者:互联网

1.编程式事务控制相关对象

1.1 PlatformTransactionManager

该接口是Spring的事务管理器,它里面提供了我们常用的操作事务的方法。

不同的技术,使用了不同的实现类实现该接口。

1.2 TransactionDefinition

是事务的定义信息对象。里面包含着事务的相关信息。里面有如下方法

方法 说明
int getIsolationLevel() 获得事务的隔离级别
int getPropogationBehavior() 获得事务的传播行为
int getTimeout() 获得超时时间
boolean isReadOnly() 是否只读

 

 

 

 

 

 

1.事务隔离级别:设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。

2.事务传播行为。

REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中,一般的选择。

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)。

 

1.3 TransactionStatus

该接口的是事务具体的运行状态。

方法 说明
boolean hasSavePoint() 是否存储回滚点

boolean isCompleted()

事务是否完成

boolean isNewTransaction()

是否是新事务
boolean isRollbackOnly() 事务是否滚回

 

 

 

 

 

 

 

被动封装事务状态信息。

 

2.基于XML的声明式事务控制

2.1 什么是声明式事务控制

采用声明的方式处理事务,这里说的声明,就是在配置文件中声明,在Spring配置文件中声明式的处理事务来代替代码式的处理事务。

 

作用:

事务管理不侵入开发的组件,因为事务管理是属于系统层面的服务,不是业务逻辑的一部分。

业务逻辑对象不会意识到正在事务管理之中。

(AOP的思想)

在不需要事务管理的时候,只需要在设定文件上修改一下,即可移除事务管理服务,无需改变代码。

注意:Srping声明式事务控制底层就是AOP

AOP的延展

2.2 声明式事务控制的实现

我们想对Service层下的transfer方法进行事务控制,目的是为了将转出和转入的操作作为一个事务整体,同成功同失败。

避免出现一方转出成功,一方转入失败仍然进行的问题。

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void transfer(String outMan, String inMan, double money) {
        //开启事务
        accountDao.out(outMan,money);
        int i = 1/0;
        accountDao.in(inMan,money);
        //提交事务
    }
}

  

我们对transfer中间进行自发的一个异常错误,我们需要做的是在执行转出方法前开启事务,在转入方法执行结束后结束事务,以达到统一的一个目的。

要达到Spring的事务控制,我们需要对xml进行控制。

    <!-- 配置一个平台事务管理器 不同的技术实现用不同的事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 通知:事务的增强-->
    <tx:advice id="txAdive" transaction-manager="transactionManager">
        <!-- 设置事务的属性信息 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事务AOP的织入 -->
    <aop:config>
        <aop:advisor advice-ref="txAdive" pointcut="execution(* com.itheima.service.impl.*.*(..))"/>
    </aop:config>

  

第一个要配置的是平台事务管理器,不同的计算对应着不同的事务管理器类,所以要注意区分,里面需要注入DataSource属性,因为Spring通过数据库连接来控制事务。

第二个要配置的是事务的增强方法(与AOP不同的是不用自己定义增强类),由于用到了tx命名空间,所以使用前要引入tx的命名空间。这里配置了用的平台事务管理器,还有对不同方法的不同事务参数配置。

第三个要配置的是事务AOP的织入,与AOP一样,pointcut里面写的是对什么范围的业务方法使用业务增强。

 

2.3 切点方法的事务参数配置

<!-- 通知:事务的增强-->
    <tx:advice id="txAdive" transaction-manager="transactionManager">
        <!-- 设置事务的属性信息 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

  

name:切点方法名称

isolation:事务的隔离级别

propagation:事务的传播行为

timeout:超时时间

read-only:是否只读

 

3.基于注解的声明式事务控制

3.1 快速实现

主要是将以下配置改成注解方式。

    <!-- 通知:事务的增强-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 设置事务的属性信息 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事务AOP的织入 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"/>
    </aop:config>

  

这些全部在业务方法类上进行,也就是Service层。

@Service("accountService")
@Transactional(isolation = Isolation.READ_COMMITTED)
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public void transfer(String outMan, String inMan, double money) {
        //开启事务
        accountDao.out(outMan,money);
        int i = 1/0;
        accountDao.in(inMan,money);
        //提交事务
    }

//    @Transactional()
    public void xxx(){}
}

  

使用@Transactional注解来完成,注解可用的属性同xml配置方式。

如果该注解出现在整个Service类上,表明该类的所有业务方法都采用该注解所对应的值来配置。

如果该注解出现在某个业务方法上,表明该业务方法的某个配置。

如果都有,服从就近原则。

 

xml配置文件要开启事件的注解驱动

<tx:annotation-driven transaction-manager="transactionManager"/>

  

 

标签:事务,accountDao,--,Spring,笔记,AOP,注解,方法,public
来源: https://www.cnblogs.com/xiaochaoheni/p/15959677.html