你所必须掌握的spring事务详解

101 阅读24分钟

1.常见题目

以下是一些常见的关于Spring事务管理的面试题:

 

  1. 什么是Spring事务管理?它的作用是什么?

  2. Spring事务管理的实现方式有哪些?请简要描述每种方式的特点。

  3. Spring的声明式事务是如何实现的?请解释其原理和流程。

  4. @Transactional注解的作用是什么?它可以应用在哪些地方?

  5. Spring事务的隔离级别有哪些?请简要描述每个级别的特点和适用场景。

  6. 事务的传播行为是什么?Spring中有哪些事务传播行为的选项?

  7. 什么是事务的回滚规则?Spring中如何配置事务的回滚规则?

  8. Spring事务的锁定机制是什么?如何避免事务的锁定问题?

  9. 如何在Spring中处理分布式事务?请解释分布式事务的概念和实现方式。

  10. Spring事务管理中的异常处理是如何工作的?如何处理事务异常的回滚和异常链?

 

这些问题涵盖了Spring事务管理的基本概念、实现方式、注解的使用、隔离级别、传播行为、回滚规则、锁定机制、分布式事务和异常处理等方面。准备这些问题的答案,并结合实际项目经验进行准确而清晰的解释,可以帮助你在面试中展现对Spring事务管理的深入理解和熟练应用能力。记得参考Spring官方文档和相关资料,加深对事务管理的理解和实践经验。

 

1.1 什么是Spring事务管理?它的作用是什么?

Spring事务管理是Spring框架提供的一种机制,用于管理数据库事务的开始、提交、回滚以及事务的隔离级别和传播行为等。它提供了一种统一的方式来管理事务,无论使用的是JDBC、Hibernate、JPA还是其他持久化框架。

 

Spring事务管理的主要作用包括以下几个方面:

 

  1. 保证数据的一致性:事务管理可以确保在一组相关的数据库操作中,要么全部操作成功提交,要么全部操作失败回滚。这样可以保证数据的一致性,避免了部分操作成功而导致数据不一致的情况。

 

  1. 提供事务的隔离级别:事务管理可以设置事务的隔离级别,以控制多个事务之间的相互影响程度。不同的隔离级别可以提供不同的数据一致性和并发性能的权衡。

 

  1. 简化事务管理代码:通过使用Spring事务管理,可以将事务管理的代码从业务逻辑中分离出来,使业务逻辑更加清晰简洁。通过注解或配置的方式,可以方便地定义事务的边界,而无需手动编写事务管理代码。

 

  1. 支持分布式事务:Spring事务管理还支持分布式事务的处理,可以跨多个数据库或服务进行事务管理,确保跨系统操作的一致性。

 

总之,Spring事务管理提供了一种灵活、统一和可扩展的机制,用于管理数据库事务,保证数据的一致性,提供事务的隔离级别,并简化事务管理的代码。它是构建可靠和高性能应用程序的重要组成部分。

 

 

Spring事务管理确实支持分布式事务处理,可以跨多个数据库或服务进行事务管理,以确保跨系统操作的一致性。Spring提供了多种方式来实现分布式事务管理,其中最常用的方式是使用JTA(Java Transaction API)来协调分布式事务。

 

在分布式事务中,涉及到多个资源(例如数据库、消息队列等)的操作,这些资源可能分布在不同的物理节点上。Spring事务管理通过集成JTA来协调这些资源的事务,以保证事务的一致性和隔离性。

 

Spring框架中的分布式事务管理通常涉及以下组件和原理:

 

  1. JTA Transaction Manager: Spring框架可以集成各种JTA事务管理器(如Bitronix、Atomikos等),这些事务管理器负责协调分布式事务的提交和回滚。

 

  1. 分布式事务协调器: 在分布式事务中,可能涉及多个资源管理器(如数据库管理器、消息队列管理器等)。分布式事务协调器负责协调各个资源管理器的事务操作,并保持事务的一致性。常见的分布式事务协调器有两阶段提交(2PC)和三阶段提交(3PC)。

 

  1. 分布式事务传播: Spring提供了不同的事务传播机制,用于控制分布式事务的传播行为。例如,可以指定事务在当前事务中运行(PROPAGATION_REQUIRED),或者新开启一个独立事务(PROPAGATION_REQUIRES_NEW)。

 

  1. 分布式事务的异常处理: 在分布式事务中,可能会出现事务操作的失败或异常情况。Spring提供了异常处理机制,可以在事务操作失败时进行回滚,以保证数据的一致性。

 

总之,Spring事务管理支持分布式事务的处理,通过集成JTA和其他相关组件,可以协调多个资源管理器的事务操作,确保跨系统操作的一致性和隔离性。在具体的实现中,需要配置相应的事务管理器、分布式事务协调器和事务传播机制,以及异常处理策略,来适应项目的分布式事务需求。

 

 

1.2 Spring事务管理的实现方式有哪些?请简要描述每种方式的特点。

Spring事务管理提供了多种实现方式,包括编程式事务管理和声明式事务管理。

 

  1. 编程式事务管理:

   - 特点:通过编写代码显式地管理事务的开始、提交或回滚。

   - 使用方式:使用TransactionTemplate或PlatformTransactionManager接口来编写事务管理代码,手动控制事务的边界和操作。

   - 优点:灵活性高,可以根据需要精确控制事务的开始和结束,适用于复杂的事务场景。

   - 缺点:代码冗长,事务管理逻辑与业务逻辑紧密耦合。

 

  1. 声明式事务管理:

   - 特点:通过在配置文件或注解中声明事务的管理方式,由Spring框架自动处理事务的开始、提交或回滚。

   - 使用方式:使用@Transactional注解或XML配置来声明事务的管理方式。

   - 优点:简化了事务管理代码,将事务逻辑与业务逻辑解耦,提高了代码的可读性和维护性。

   - 缺点:相对于编程式事务管理,灵活性稍低,不适用于复杂的事务场景。

 

  1. 注解驱动事务管理:

   - 特点:通过在方法或类级别上使用@Transactional注解来声明事务的属性。

   - 使用方式:在需要事务管理的方法或类上添加@Transactional注解,并配置相应的事务属性。

   - 优点:简化了配置,提供了更细粒度的事务控制,可灵活指定事务的传播行为、隔离级别等属性。

   - 缺点:对于大型项目,可能需要在多个地方重复添加注解,增加了维护成本。

 

总的来说,编程式事务管理适用于复杂的事务场景,需要精确控制事务的边界和操作;声明式事务管理适用于一般的事务场景,简化了事务管理代码;注解驱动事务管理提供了更便捷的方式来声明事务属性,提高了代码的可读性和维护性。选择合适的事务管理方式取决于具体的项目需求和开发团队的偏好。

 

1.3 Spring的声明式事务是如何实现的?请解释其原理和流程。

Spring的声明式事务是通过AOP(面向切面编程)来实现的。在声明式事务中,开发者只需要通过配置或注解来定义事务的行为,而不需要显式编写事务管理代码。

 

原理和流程如下:

 

  1. 配置事务管理器:在Spring配置文件中配置一个事务管理器(如DataSourceTransactionManager),用于管理事务的开始、提交和回滚。

 

  1. 定义事务切点:通过XML配置或注解,定义事务切点,即指定哪些方法需要被事务管理。切点可以是类级别的,也可以是方法级别的。

 

  1. 生成代理对象:使用AOP技术,Spring会根据事务切点自动生成一个代理对象。该代理对象包装了原始的目标对象,拦截了切点方法的调用。

 

  1. 事务管理的织入:在代理对象中,Spring会根据配置的事务属性,在切点方法的前后添加事务管理的逻辑。

 

  1. 事务的开始:当调用切点方法时,代理对象会首先触发事务的开始。事务管理器会打开一个数据库连接,并将其绑定到当前线程。

 

  1. 执行业务逻辑:在事务开始后,代理对象会执行切点方法的业务逻辑。

 

  1. 异常处理和事务回滚:如果切点方法抛出异常,代理对象会捕获该异常,并触发事务的回滚操作。回滚操作会将数据库连接的事务状态设置为回滚,并释放数据库连接。

 

  1. 事务的提交:如果切点方法正常执行完毕,代理对象会触发事务的提交操作。提交操作会将数据库连接的事务状态设置为提交,并释放数据库连接。

 

  1. 释放资源:无论事务是回滚还是提交,代理对象都会释放数据库连接和其他资源,并将其从当前线程解绑。

 

总的流程就是通过AOP将事务管理逻辑织入到切点方法中,实现了声明式事务的管理。开发者只需要关注业务逻辑的编写,而不需要关心事务管理的具体实现。这样可以提高代码的可读性和维护性,同时降低了事务管理的复杂性。

 

以下是一个简化的示例代码,演示了如何使用Spring的AOP来实现声明式事务:

 

  1. 定义一个切面类 TransactionAspect,它是一个普通的Java类,并使用 @Aspect 注解进行标识。

 

```java
@Aspect
public class TransactionAspect {


    @Autowired
    private PlatformTransactionManager transactionManager;


    @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
    public void transactionalMethods() {}


    @Around("transactionalMethods()")
    public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
        // 开始事务
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        
        try {
            // 执行目标方法
            Object result = joinPoint.proceed();
            
            // 提交事务
            transactionManager.commit(status);
            
            return result;
        } catch (Throwable e) {
            // 回滚事务
            transactionManager.rollback(status);
            throw e;
        }
    }
}
```

 

  1. 配置Spring,将切面类注册为一个切面,并启用AOP。

 

```xml
<bean id="transactionAspect" class="com.example.TransactionAspect" />


<aop:aspectj-autoproxy />
```

 

在上面的示例中:

 

  • TransactionAspect 类使用 @Aspect 注解标识,表示它是一个切面类。

  • @Pointcut 注解定义了一个切点,用于匹配所有被 @Transactional 注解标记的方法。

  • @Around 注解表示在目标方法执行前后织入增强逻辑。

  • manageTransaction 方法中,通过 PlatformTransactionManager 来管理事务的开始、提交和回滚。

 

通过以上配置,当标记了 @Transactional 注解的方法被调用时,AOP会拦截并织入事务管理逻辑。

 

请注意,以上只是一个简化的示例,实际的AOP配置可能涉及更多的细节和配置。具体的配置方式取决于你的项目结构和需求。

 

 

1.4 @Transactional注解的作用是什么?它可以应用在哪些地方?

@Transactional注解是Spring框架提供的一个注解,用于声明事务的属性和行为。它的作用是将带有该注解的方法或类纳入到事务管理中,以确保这些方法或类在执行时能够按照事务的要求进行事务管理。

 

@Transactional注解可以应用在以下几个地方:

 

  1. 在方法上:将带有@Transactional注解的方法纳入到事务管理中,方法执行时会开启事务,根据注解的属性来决定事务的传播行为、隔离级别、回滚规则等。

 

  1. 在类上:将整个类中的方法都纳入到事务管理中,类中的所有带有@Transactional注解的方法都会应用相同的事务属性。

 

  1. 在接口上:当接口的方法被实现类实现时,带有@Transactional注解的方法会被纳入到事务管理中。

 

@Transactional注解提供了一系列属性,可以根据需求进行配置,例如:

 

  • propagation:指定事务的传播行为,定义了方法调用之间的事务关系。

  • isolation:指定事务的隔离级别,定义了事务并发访问数据库时的行为。

  • readOnly:指定事务是否为只读事务,如果是只读事务,将优化数据库访问性能。

  • timeout:指定事务的超时时间,当事务执行时间超过指定时间时,将回滚事务。

  • rollbackForrollbackForClassName:指定哪些异常触发事务回滚。

  • noRollbackFornoRollbackForClassName:指定哪些异常不触发事务回滚。

 

通过在适当的地方使用@Transactional注解,可以轻松管理事务,并确保数据的一致性和完整性。

 

1.5 Spring事务的隔离级别有哪些?请简要描述每个级别的特点和适用场景。

Spring事务的隔离级别是指多个事务并发访问数据库时的隔离程度,用于控制数据的一致性和并发访问的效果。Spring框架支持以下五种事务隔离级别:

 

  1. DEFAULT(默认):使用数据库默认的隔离级别。通常为数据库设置的默认级别,不进行显式设置。

 

  1. READ_UNCOMMITTED(读未提交):最低的隔离级别,允许事务读取未提交的数据修改。存在脏读、不可重复读和幻读的问题,一般不推荐使用。

 

  1. READ_COMMITTED(读已提交):保证一个事务只能读取到已经提交的数据。解决了脏读的问题,但仍然可能出现不可重复读和幻读的问题。

 

  1. REPEATABLE_READ(可重复读):保证在同一个事务中多次读取同一数据时,结果保持一致。解决了脏读和不可重复读的问题,但仍然可能出现幻读的问题。

 

  1. SERIALIZABLE(串行化):最高的隔离级别,事务串行执行,完全解决了脏读、不可重复读和幻读的问题。但由于事务串行执行,可能会导致并发性能问题,只在特殊场景下使用。

 

不同的隔离级别适用于不同的场景和需求:

 

  • 如果对并发性能要求不高,但要求数据的一致性和完整性,可以选择SERIALIZABLE隔离级别。

  • 如果对并发性能有一定要求,并且可以容忍一定程度的不一致性,可以选择REPEATABLE_READ隔离级别。

  • 如果对并发性能要求较高,但可以容忍一定程度的数据不一致,可以选择READ_COMMITTED隔离级别。

  • 如果对并发性能要求非常高,但可以容忍较大的数据不一致,可以选择READ_UNCOMMITTED隔离级别。

  • 在一般情况下,使用默认的隔离级别即可,根据具体的业务需求进行调整。

 

在Spring中,可以通过在@Transactional注解中的isolation属性来设置事务的隔离级别,例如:

```java
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void someMethod() {
    // 事务方法的逻辑
}
```

注意:不同的数据库对隔离级别的支持可能有所不同,请根据具体的数据库来选择合适的隔离级别。

 

 

Spring事务的隔离级别与数据库的隔离级别是对应的。Spring框架中的事务隔离级别与数据库的隔离级别保持一致,因为底层的事务管理是通过数据库的事务来实现的。

不同数据库对事务隔离级别的支持可能会有所差异,但大多数数据库都支持标准的四种隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。在Spring中,可以使用相应的常量值来设置事务的隔离级别。

因此,在使用Spring进行事务管理时,设置的事务隔离级别将直接映射到底层数据库的隔离级别,确保事务在数据库层面具有相应的隔离性。这样可以确保数据在并发访问时的一致性和正确性。

 

 

 

1.6 事务的传播行为是什么?Spring中有哪些事务传播行为的选项?

 

事务的传播行为是指在多个事务方法相互调用时,如何处理事务的传播关系。当一个事务方法调用另一个事务方法时,传播行为定义了被调用方法应该如何与现有事务进行交互。

 

在Spring中,事务传播行为由Propagation枚举类定义,提供了以下选项:

 

  1. REQUIRED(默认值):如果当前存在事务,则加入该事务,如果没有事务,则创建一个新事务。被调用方法将在当前事务中执行,与调用方共享同一个事务。

 

  1. SUPPORTS:如果当前存在事务,则加入该事务,如果没有事务,则以非事务方式执行。被调用方法将根据调用方的事务执行情况进行处理。

 

  1. MANDATORY:要求当前存在事务,如果没有事务,则抛出异常。被调用方法必须在一个已存在的事务中执行。

 

  1. REQUIRES_NEW:创建一个新事务,并挂起当前事务(如果存在)。被调用方法将在自己的事务中执行,与调用方事务相互独立。

 

  1. NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则将其挂起。被调用方法将在没有事务的环境中执行。

 

  1. NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。被调用方法不能在事务中执行。

 

  1. NESTED:如果当前存在事务,则在嵌套事务中执行。被调用方法将创建一个保存点(savepoint),可以回滚到该保存点。如果没有事务,则行为类似于REQUIRED。

 

这些传播行为选项允许开发者根据业务需求灵活地控制事务的行为,确保事务在多个方法之间正确地传播和管理。

 

 

 

当我们在开发一个电商系统时,可能有以下场景:

 

  1. 用户下单:有一个下单服务方法 placeOrder(),它会在数据库中创建订单记录,并扣除用户的账户余额。这个方法需要在一个独立的事务中执行,以保证数据的一致性和完整性。

 

  1. 发送邮件通知:在下单后,我们可能需要发送邮件通知用户订单已成功创建。有一个发送邮件的服务方法 sendEmailNotification(),它会通过邮件服务发送邮件给用户。这个方法在发送邮件的过程中并不需要开启一个新的事务,而是应该在已存在的事务中执行,以确保邮件发送和订单创建在同一个事务中。

 

在这个例子中,我们可以使用事务传播行为来管理这两个方法的事务:

 

  1. 对于 placeOrder() 方法,我们可以使用 @Transactional 注解来指定事务的传播行为为 REQUIRED。这表示如果当前已存在一个事务,则 placeOrder() 方法将在该事务中执行;如果当前没有事务,则会创建一个新的事务。

 

  1. 对于 sendEmailNotification() 方法,我们可以将其声明为一个普通的方法,不添加 @Transactional 注解。这样,sendEmailNotification() 方法将会在调用它的上层事务方法中执行,即在 placeOrder() 方法的事务中执行。

 

通过这样的配置,我们可以实现在下单过程中,订单创建和邮件发送在同一个事务中进行管理,确保数据的一致性和完整性。同时,也允许在不同的方法中灵活地控制事务的传播行为,以满足不同的业务需求。

 

1.7 什么是事务的回滚规则?Spring中如何配置事务的回滚规则?

事务的回滚规则指定了在何种情况下事务应该回滚。当某些特定的异常被抛出或满足一定的条件时,事务将自动回滚,将之前的操作撤销并恢复到事务开始之前的状态。

 

在 Spring 中,可以通过 @Transactional 注解的 rollbackFornoRollbackFor 属性来配置事务的回滚规则。

 

  • rollbackFor 属性指定了哪些异常触发事务回滚。它接受一个异常类或异常类数组作为参数。当抛出指定的异常或其子类时,事务将回滚。

 

  • noRollbackFor 属性指定了哪些异常不触发事务回滚。它接受一个异常类或异常类数组作为参数。当抛出指定的异常或其子类时,事务不会回滚。

 

以下是一个示例,演示了如何配置事务的回滚规则:

 

```java
@Service
@Transactional(rollbackFor = {SQLException.class}, noRollbackFor = {NullPointerException.class})
public class MyService {


    @Transactional(rollbackFor = {CustomException.class})
    public void performTransaction() {
        try {
            // 执行一些数据库操作
            // ...
        } catch (SQLException ex) {
            throw new SQLException("数据访问异常", ex);
        } catch (NullPointerException ex) {
            throw new NullPointerException("空指针异常");
        } catch (CustomException ex) {
            throw new CustomException("自定义异常");
        }
    }
}
```

 

在上述示例中:

 

  • MyService 类级别的 @Transactional 注解指定了回滚规则,即当出现 SQLException 异常时事务回滚,但不会回滚 NullPointerException 异常。

 

  • performTransaction() 方法级别的 @Transactional 注解覆盖了类级别的注解,并指定了回滚规则,即当出现 CustomException 异常时事务回滚。

 

通过配置适当的回滚规则,可以灵活地控制事务的回滚行为,以满足业务需求和异常处理的要求。

 

 

1.8 Spring事务的锁定机制是什么?如何避免事务的锁定问题?

 

Spring 事务的锁定机制主要是通过数据库的锁定机制来实现的。当一个事务访问某个数据时,会对该数据进行锁定,阻止其他事务对该数据进行修改,直到当前事务完成提交或回滚操作。

 

事务的锁定问题可能导致死锁和性能下降。为了避免事务的锁定问题,可以采取以下策略:

 

  1. 尽量缩小事务的范围:将事务限定在必要的操作上,减少锁定的时间和范围。不要在事务中包含耗时长的操作,尽量将其移到事务之外。

 

  1. 合理设置事务的隔离级别:根据具体需求选择合适的事务隔离级别,避免过高的隔离级别带来的锁定问题。例如,在读取大量数据但不需要保证数据一致性的场景下,可以选择较低的隔离级别,如 READ UNCOMMITTED。

 

  1. 使用乐观锁机制:通过版本控制或时间戳等机制,在进行数据更新时,先读取数据并记录版本信息,然后在更新时比较版本信息,如果发现冲突,则放弃更新操作,避免了显式的锁定。

 

  1. 合理设计数据库表结构和索引:良好的表结构设计和索引设计可以减少数据库的锁定和冲突,提高并发性能。

 

  1. 避免长事务:长事务会占用锁资源的时间较长,增加了锁定问题的概率。尽量设计短小精悍的事务,尽早提交或回滚。

 

  1. 减少事务并发冲突:分析业务流程,合理划分事务边界,减少事务之间的并发冲突,避免多个事务同时修改同一组数据。

 

以上策略可以帮助减少事务的锁定问题,提高事务的并发性能和系统的稳定性。根据具体的业务场景和需求,可以选择适合的策略或进行针对性的优化。

 

 

1.9 如何在Spring中处理分布式事务?请解释分布式事务的概念和实现方式。

分布式事务是指涉及多个独立服务或数据库的事务操作。在分布式环境下,由于涉及多个资源,保持事务的一致性和原子性变得更加复杂。为了解决分布式事务的问题,可以使用以下几种方式实现:

 

  1. 基于本地事务的两阶段提交(2PC):2PC 是一种经典的分布式事务协议,它通过协调者(Coordinator)和参与者(Participant)之间的协作来实现事务的提交或回滚。在 Spring 中,可以使用 JTA(Java Transaction API)来实现分布式事务的管理,通过配置 JTA 事务管理器和参与者资源来实现分布式事务。

 

  1. 基于消息队列的最终一致性:使用消息队列作为分布式事务的中间件,将事务操作转化为消息发送和消费的过程。参与者将事务操作作为消息发送到消息队列,然后由消费者异步处理消息,并完成最终一致性的操作。

 

  1. 分布式事务框架:除了传统的 2PC 和消息队列,还有一些分布分布式事务框架,如 Atomikos、Bitronix、Narayana 等,这些框架提供了高级的分布式事务管理功能,可以简化开发人员处理分布式事务的复杂性。这些框架通常通过协调者和参与者之间的协作来实现事务的一致性和原子性,并提供了可靠的事务日志和恢复机制。

 

在 Spring 中,可以使用分布式事务框架来处理分布式事务。通过配置适当的事务管理器和参与者资源,Spring 可以与分布式事务框架集成,实现分布式事务的管理和协调。常见的做法是配置分布式事务管理器,如 AtomikosTransactionManager 或 BitronixTransactionManager,然后在 Spring 事务注解中使用 @Transactional 注解来标记需要参与分布式事务的方法。

 

总结来说,处理分布式事务需要考虑多个独立服务或数据库之间的事务一致性和原子性。可以通过传统的两阶段提交协议、基于消息队列的最终一致性或使用分布式事务框架来实现分布式事务的管理。在 Spring 中,可以配置适当的事务管理器和参与者资源,使用 @Transactional 注解标记参与分布式事务的方法。

 

 

1.10 Spring事务管理中的异常处理是如何工作的?如何处理事务异常的回滚和异常链?

在 Spring 事务管理中,异常处理是通过事务管理器来实现的。当事务方法抛出异常时,Spring 事务管理器会根据配置进行相应的异常处理操作,包括事务的回滚和异常链的构建。

 

  1. 事务回滚:

   - 默认情况下,Spring 事务管理器会将所有未被捕获的异常视为事务回滚的触发条件,即任何未处理的异常都会导致事务回滚。

   - 可以通过在 @Transactional 注解上配置 rollbackFor 属性,指定特定的异常类型,当抛出指定类型的异常时触发事务回滚。

   - 可以在方法内部手动抛出 RuntimeException 或继承自 RuntimeException 的异常,同样会触发事务回滚。

 

  1. 异常链:

   - 当事务方法抛出异常时,Spring 事务管理器会将异常封装为一个事务异常,并将其作为原始异常的一个 cause 连接起来,形成一个异常链。

   - 异常链的目的是为了提供更好的故障诊断和错误处理能力。通过异常链,可以跟踪到事务方法内部发生的异常及其根源。

   - 异常链的构建是由 Spring 事务管理器自动完成的,无需手动干预。

 

总结来说,Spring 事务管理器会根据异常的类型和配置的回滚规则来决定是否触发事务回滚。同时,它会将事务异常封装为一个异常链,以提供更详细的异常信息和错误追踪能力。这样可以确保事务的一致性,并提供更好的异常处理和故障诊断能力。