Bootstrap

Spring 5 中文解析数据存储篇-理解Spring事物抽象

Spring核心篇章:

Spring测试篇章:

Spring存储篇章:

完整

1.2 理解Spring框架事物抽象

Spring事务抽象的关键是事务策略的概念。事务策略由定义,特别是用于命令式事务管理的接口和用于响应式事务管理的接口。以下清单显示了 API的定义:

public interface PlatformTransactionManager extends TransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

尽管你可以从应用程序代码中以使用它,但它主要是一个服务提供接口(SPI)。由于是接口,因此可以根据需要轻松对其进行模拟或存根。它与之类的查找策略无关。与Spring框架IoC容器中的任何其他对象(或bean)一样,定义了实现。这一优点使Spring框架事务成为值得抽象的,即使在使用时也是如此。与直接使用相比,你可以更轻松地测试事务代码。

同样,为了与Spring的理念保持一致,可以由任何接口方法抛出的未检查异常(也就是说,它扩展了类)。事物基础架构故障几乎总是致命的。在极少数情况下,应用程序代码实际上可以从事务失败中恢复,应用程序开发人员仍然可以选择捕获和处理。实际一点是,开发人员没有被迫这样做。

方法根据参数返回对象。如果当前调用堆栈中存在匹配的事务,则返回的可能表示一个新事务或一个现有事务。后一种情况的含义是,与Java EE事务上下文一样,与执行线程相关联。

从Spring框架5.2开始,Spring还为使用响应式类型或协程的响应式应用程序提供了事务管理抽象。以下清单显示了由定义的事务策略:

public interface ReactiveTransactionManager extends TransactionManager {

    Mono getReactiveTransaction(TransactionDefinition definition) throws TransactionException;

    Mono commit(ReactiveTransaction status) throws TransactionException;

    Mono rollback(ReactiveTransaction status) throws TransactionException;
}

响应式事务管理器主要是服务提供接口(SPI),尽管你可以从应用程序代码中以使用它。由于是接口,因此可以根据需要轻松对其进行模拟或存根。

接口指定:

  • 传播:通常,事务范围内的所有代码都在该事务中运行。但是,如果在已存在事务上下文的情况下运行事务方法,则可以指定行为。例如,代码可以在现有事务中继续运行(常见情况),或者可以暂停现有事务并创建新事务。Spring提供了 熟悉的所有事务传播选项。要了解有关Spring中事务传播的语义的信息,请参阅

  • 隔离:此事务与其他事务的工作隔离的程度。例如,此事务能否看到其他事务未提交的写入?

  • 超时:该事务在超时之前将运行多长时间,并由基础事务基础结构自动回滚。

  • 只读状态:当代码读取但不修改数据时,可以使用只读事务。在某些情况下,例如使用时,只读事务可能是有用的优化。

这些设置反映了标准的事物概念。如有必要,请参考讨论事务隔离级别和其他核心事务概念的资源。了解这些概念对于使用Spring框架或任何事务管理解决方案至关重要。

接口为事务代码提供了一种控制事务执行和查询事务状态的简单方法。这些概念应该很熟悉,因为它们对于所有事务API都是通用的。以下清单显示了接口:

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {

    @Override
    boolean isNewTransaction();

    boolean hasSavepoint();

    @Override
    void setRollbackOnly();

    @Override
    boolean isRollbackOnly();

    void flush();

    @Override
    boolean isCompleted();
}

无论你在Spring中选择声明式还是编程式事务管理,定义正确的实现都是绝对必要的。通常,你可以通过依赖注入来定义此实现。实现通常需要了解其工作环境:、、等。

实现通常需要了解其工作环境:、、等。以下示例显示了如何定义本地实现(在这种情况下,使用纯)。

你可以通过创建类似于以下内容的bean来定义数据源:


    
    
    
    

然后,相关的 Bean定义将引用定义。它应类似于以下示例:


    

如果你在Java EE容器中使用,则可以使用通过获得的容器以及Spring的。以下示例显示了和查找:




    

    

    


不需要了解数据源(或任何其他特定资源),因为它使用了容器的全局事务管理基础结构。

 bean的先前定义使用jee名称空间中的标记。有关更多信息,参考

你还可以轻松使用本地事务,如以下示例所示。在这种情况下,你需要定义一个,你的应用程序代码可使用该 获取 实例。

 bean定义与先前显示的本地示例相似,因此在以下示例中未显示。

如果通过查找数据源(由任何非事务管理器使用)并由Java EE容器管理,则该数据源应该是非事务性的,因为Spring框架(而不是Java EE容器)管理事务。

在这种情况下, bean是类型。就像需要引用数据源一样,需要引用。以下示例声明了和 bean:


    
    
        
            org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml
        
    
    
        
            hibernate.dialect=${hibernate.dialect}
        
    



    

如果使用和Java EE容器管理的事务,则应使用与前面的 示例相同的,如以下示例所示:


如果使用,则无论使用哪种数据访问技术(无论是、 或任何其他受支持的技术),事务管理器定义都应该相同。这是由于事务是全局事务,它可以征用任何事务资源。

在所有这些情况下,无需更改应用程序代码。你可以仅通过更改配置来更改事务的管理方式,即使更改意味着从本地事务转移到全局事务,反之亦然。

作者

个人从事金融行业,就职过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就职于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。关注公众号:青年IT男 获取最新技术文章推送!

博客地址: 

CSDN: 

微信公众号: 

技术交流群: