学习笔记--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方法进行事务控制,目的是为了将转出和转入的操作作为一个事务整体,同成功同失败。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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进行控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 配置一个平台事务管理器 不同的技术实现用不同的事务管理器-->
<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 切点方法的事务参数配置

1
2
3
4
5
6
7
8
<!-- 通知:事务的增强-->
    <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 快速实现

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

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 通知:事务的增强-->
<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层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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配置文件要开启事件的注解驱动

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

  

 

posted @   小超和你  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?
点击右上角即可分享
微信分享提示