Spring事务(Java学习笔记)

  1. 事务就是逻辑上的一组操作,要么都执行,都要都不执行。
  2. 事务能否生效数据库引擎是否支持事务是关键。

事务的特性(ACID):

  1. 原子性(Atomicity): 一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
  2. 一致性(Consistency): 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
  3. 隔离性(Isolation): 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  4. 持久性(Durability): 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

Spring对事务的支持

我们都知道保证事务的原子性,就需要在发生异常的时候,对已经执行的操作进行回滚,在Mysql中,恢复机制是通过回滚日志来实现,所以事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行的过程中遇到异常的话,我们就直接利用回滚日志中的信息将数据进行回滚到修改之前的样子即可。并且日志回滚会咸鱼数据持久化到磁盘上。这样就保证了就算遇到数据库宕机,当用户再次启动数据库的时候,数据库还能通过查询回滚日志来回滚之前未完成的操作。

Spring支持两种方式的事务管理

通过TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用。
实例:

//TransationTemplate
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                try {

                    // ....  业务代码
                } catch (Exception e){
                    //回滚
                    transactionStatus.setRollbackOnly();
                }

            }
        });
}

使用 TransactionManager 进行编程式事务管理的示例代码如下:

@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

  TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
          try {
               // ....  业务代码
              transactionManager.commit(status);
          } catch (Exception e) {
              transactionManager.rollback(status);
          }
}

事务管理的两种方式

事务管理的方式说明
编程式事务管理编程式事务管理是编写代码实现事务管理,这种方式是能够在代码中精确地定会一事务发展的边界,我们可以根据需求规定事务从哪开始,到哪里结束
声明式事务管理Spring声明式事务管理在底层采用了AOP技术,其最大的优点在于无需通过编程的方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将书屋规则应用到业务逻辑中。

注意:
编程式事务对事物的控制细粒度更高,我们能够精确的控制事务的边界,事务的开始和结束完全取决于我们的需求,但对这种方式存在一个致命的缺点,那就是事务规则和业务代码的耦合度高,难以维护,因此我们很少使用这种方式对事务进行管理。
声明式事务易用性更高,对业务代码没有侵入性,耦合度地,易于维护,因此这种方式也是我们常用的事务管理方式。
Spring声明式事务的方式有以下两种:
基于XML方式的声明式事务管理。
基于注解方式的声明式事务管理。

使用 @Transactional注解进行事务管理的示例代码如下:

@Transactional(propagation = Propagation.REQUIRED)
public void aMethod {
  //do something
  B b = new B();
  C c = new C();
  b.bMethod();
  c.cMethod();
}

Spring 事务管理接口介绍

Spring框架中,事务相关最重要的3个接口:

  1. PlatformTransactionManager:(平台)事务管理器,Spring事务策略的核心。
  2. TransactionDefinition:事务定义信息(事务隔离级别,传播行为,超时,只读,回滚规则)。
  3. TransactionStatus:事务运行状况
    我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinition 和 TransactionStatus 这两个接口可以看作是事务的描述。PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

PlatformTransactionManager接口

PlatformTransactionManager接口是Spring提供的事务管理器接口,用于管理事务。Spring将事务的配置详细信息封装到TransactionDefinition对象中,然后通过事务管理器的getTransaction()方法获得事务的状态(TransactionStatus),并对事务尽心进一步操作:

该接口提供了三个事务操作方法:

  1. TransactionStatus getTransaction(Transaction definition):用于获取事务状态信息。
  2. void commit (TransactionStatus status):用于提交事务。
  3. void rollback(TransactionStatus status):用于回滚事务。
public interface TransactionDefinition {
    int getPropagationBehavior(); //获取事务的传播行为
    int getIsolationLevel(); //获取事务的隔离级别
    String getName(); //获取事务的名称
    int getTimeout();//获取事务的超时时间
    boolean isReadOnly();//获取事务是否可读
}

事务的隔离级别

在开发环境中,我们会出现多个事务对同一个数据进行不同的操作,来实现各自的任务的情况,此时就有可能导致脏读,幻读以及不可重读等问题。在理想状态下,事务之间是完全隔离的,这自然不会出现上诉问题,但事务隔离会导致性能问题,并且并不是所有的应用都需要事务的完全隔离,因此有时应用程序在事务隔离上有一定的灵活性。
Spring提供了以下的隔离级别:

方法说明
ISOLATION_DEFAULT使用后端数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED允许读取尚未提交的更改,可能导致脏读、幻读和不可重复读
ISOLATION_READ_COMMITTEDOracle 默认级别,允许读取已提交的并发事务,防止脏读,可能出现幻读和不可重复读
ISOLATION_REPEATABLE_READMySQL 默认级别,多次读取相同字段的结果是一致的,防止脏读和不可重复读,可能出现幻读
ISOLATION_SERIALIZABLE完全服从 ACID 的隔离级别,防止脏读、不可重复读和幻读

事务的传播行为

事务传播行为(propagation behavior)指的是,当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行。例如,事务方法 A 在调用事务方法 B 时,B 方法是继续在调用者 A 方法的事务中运行呢,还是为自己开启一个新事务运行,这就是由事务方法 B 的事务传播行为决定的。
事务方法指的是能让数据库表数据发生改变的方法,例如新增数据、删除数据、修改数据的方法。
Spring 提供了以下 7 种不同的事务传播行为。

名称说明
PROPAGATION_MANDATORY支持当前事务,如果不存在当前事务,则引发异常。
PROPAGATION_NESTED如果当前事务存在,则在嵌套事务中执行。
PROPAGATION_NEVER不支持当前事务,如果当前事务存在,则引发异常。
PROPAGATION_NOT_SUPPORTED不支持当前事务,始终以非事务方式执行。
PROPAGATION_REQUIRED默认传播行为,如果存在当前事务,则当前方法就在当前事务中运行,如果不存在,则创建一个新的事务,并在这个新建的事务中运行。
PROPAGATION_REQUIRES_NEW创建新事务,如果已经存在事务则暂停当前事务。
PROPAGATION_SUPPORTS支持当前事务,如果不存在事务,则以非事务方式执行。

TransactionStatus 接口

TransactionStatus 接口提供了一些简单的方法,来控制事务的执行、查询事务的状态,接口定义如下。

public interface TransactionStatus extends SavepointManager {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    boolean isCompleted();
}

该接口中各方法说明如下。

名称 说明

  1. boolean hasSavepoint() 获取是否存在保存点
  2. boolean isCompleted() 获取事务是否完成
  3. boolean isNewTransaction() 获取是否是新事务
  4. boolean isRollbackOnly() 获取事务是否回滚
  5. void setRollbackOnly() 设置事务回滚

学习地址

原文链接1
原文链接2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值