首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring 事务

Spring 事务

作者头像
希希里之海
发布2019-08-20 11:28:32
发布2019-08-20 11:28:32
60400
代码可运行
举报
文章被收录于专栏:weixuqin 的专栏weixuqin 的专栏
运行总次数:0
代码可运行

Spring 事务

关于理论性的内容,我在之前的一篇文章中介绍过,这里不再过多阐述,这里给出之前文章的链接:Spring 事务管理

什么是事务

是一组逻辑操作,要么执行,要么不执行。

事务的特性

ACID (原子性、一致性、隔离性、持久性)

并发事务带来的问题

  • 脏读
  • 丢失修改
  • 不可重复读
  • 幻读

配置事务管理器

代码语言:javascript
代码运行次数:0
运行
复制
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- 数据源 -->
    <property name="dataSource" ref="dataSource" />
</bean>

Spring 事务接口

  • PlatformTransactionManager:(平台)事务管理器
  • TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
  • TransactionStatus: 事务运行状态
1. PlatfromTransactionManager 接口介绍:

该接口主要有三个方法:

代码语言:javascript
代码运行次数:0
运行
复制
Public interface PlatformTransactionManager()...{

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; 

    Void commit(TransactionStatus status) throws TransactionException;  

    Void rollback(TransactionStatus status) throws TransactionException;  
} 
  • getTransaction:根据指定的传播行为,返回当前活动的事务或创建一个新事务
  • commit:使用事务目前的状态提交事务
  • rollback:对执行的事务进行回滚

一般情况下用的比较多的就是 commit 提交事务和 rollback 回滚事操作了。

2. TransactiDefinition 接口介绍:

该接口主要定义了一些表示事务属性(如隔离级别,传播行为等)的常量。当然还有一些方法,仅有篇幅,不对方法做介绍。

(1)事务隔离级别(定义了一个事务可能受其他并发事务影响的程度):

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

  • TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别。Mysql 默认采用 REPEATALBE-READ 隔离级别;Oracle 默认采用 READ_COMMITTED 隔离级别。
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • TransactionDefinition.ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • TransactionDefinition.ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • TransactionDefinition.ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
(2)事务传播行为(为了解决业务层方法之间互相调用的事务问题):

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

支持当前事务的情况:

  • TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

不支持当前事务的情况:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

其他情况:

  • TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED
(3)TransactionStatus 接口介绍

TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息。 TransactionStatus 接口方法如下:

代码语言:javascript
代码运行次数:0
运行
复制
public interface TransactionStatus{
    boolean isNewTransaction(); // 是否是新的事物
    boolean hasSavepoint(); // 是否有恢复点
    void setRollbackOnly();  // 设置为只回滚
    boolean isRollbackOnly(); // 是否为只回滚
    boolean isCompleted; // 是否已完成
} 

举例

事务操作一般都是在 service 层编写,结合增删改查方法。我举个栗子:

代码语言:javascript
代码运行次数:0
运行
复制
class Test {
    
    private PlatformTransactionManager transactionManager;
    
    public void saveFromDB() {

        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);

        try {      
            // 增删改查操作(使用 dao 中的方法)
            //...
            transactionManager.commit(transactionStatus);
        
            // 删除本地缓存操作
            //...
        
        } catch (Exception e) {
            transactionManager.rollback(transactionStatus);
        
        }
    }
}

这里需要注意的是:当我们执行增删查改操作时,应该在 service 层添加事务,并且删除之前的缓存(本地缓存和 redis 缓存),然后再执行增删查改操作,这三方面都兼顾到了才是一个比较好的增删查改操作。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring 事务
    • 什么是事务
    • 事务的特性
    • 并发事务带来的问题
    • 配置事务管理器
    • Spring 事务接口
    • 举例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档