天天看點

Spring 5 中文解析資料存儲篇-程式設計式事物管理

Spring核心篇章: Spring 5 中文解析之核心篇-IoC容器 Spring 5 中文解析核心篇-IoC容器之依賴關系 Spring 5 中文解析核心篇-IoC容器之Bean作用域 Spring 5 中文解析核心篇-IoC容器之自定義Bean性質 Spring 5 中文解析核心篇-IoC容器之BeanDefinition繼承與容器拓展點 Spring 5 中文解析核心篇-IoC容器之基于注解的容器配置 Spring 5 中文解析核心篇-IoC容器之類路徑掃描群組件管理 Spring 5 中文解析核心篇-IoC容器之JSR330标準注解 Spring 5 中文解析核心篇-IoC容器之基于Java容器配置 Spring 5 中文解析核心篇-IoC容器之Environment抽象 Spring 5 中文解析核心篇-IoC容器之ApplicationContext與BeanFactory Spring 5 中文解析核心篇-IoC容器之Resources Spring 5 中文解析核心篇-IoC容器之資料校驗、資料綁定和類型轉換 Spring 5 中文解析核心篇-IoC容器之SpEL表達式 Spring 5 中文解析核心篇-IoC容器之AOP程式設計(上) ") Spring 5 中文解析核心篇-IoC容器之AOP程式設計(下) Spring 5 中文解析核心篇-IoC容器之Spring AOP API Spring測試篇章: Spring 5 中文解析測試篇-Spring測試 Spring 5 中文解析核心篇-內建測試之概要和內建測試注解 Spring 5 中文解析核心篇-內建測試之TestContext(上) Spring 5 中文解析核心篇-內建測試之TestContext(中) Spring 5 中文解析測試篇-內建測試之TestContext(下) Spring 5 中文解析測試篇-Spring MVC測試架構 Spring 5 中文解析測試篇-WebTestClient Spring存儲篇章: Spring 5 中文解析資料存儲篇-Spring架構的事物支援模型的優勢

[Spring 5 中文解析資料存儲篇-事務同步和聲明式事物管理

](

https://mp.weixin.qq.com/s?__biz=MzA3NDgzODYzNg==&tempkey=MTA3OV91TU8vcGlxSXdvTGNhZ2o0a3p2RXZvSGpJeXNCMmNCUkszbU9OZzVSc09rT19Zejl6b3JCWHZHU0JfN3ZrVDhhbzZUV3BfS2s3aHFEakhPb3V4dXVkMVp4ajFfZllOcnM2N3huU2d1ZUJZZlN6T1lZNVVKWHJjOWRkdEg3Uzg3RmpFRzZXbHMzQ3lFUUEwd1JqTl9JOGZzWGxMYWh6N1lhY05DYnFRfn4%3D&chksm=1f7b0caa280c85bcce8c4ffe9fb21629f683d5d9127116dae91dc9b9cbd2f367a19514fef76f#rd) [Spring 5 中文解析資料存儲篇-@Transactional使用 https://mp.weixin.qq.com/s?__biz=MzA3NDgzODYzNg==&tempkey=MTA3OV9RNU1VNnhsa0ZkRlhBb3Fla3p2RXZvSGpJeXNCMmNCUkszbU9OZzVSc09rT19Zejl6b3JCWHZHU0JfNTZ4dWhENjFrNUV6dlpieWYxVndQRlBNNkFRZVBFWlVyZHdiQlhTMmZMM0g0TnppT040Nk5QUU1rcEpNY2FDN09nZnNPeG5WTU8wajZCNUowaHZnTHhZcGpYdVRlNXQzWTZUSV8yOEpJNl9nfn4%3D&chksm=1f7b0cb3280c85a5682b1c9ea3cf7d2a69abdd6fe9147ed4335a5d5cfbef7c04ed314bd389de#rd) 完整 電子書位址 Spring架構通過使用以下兩種方式提供程式設計式事務管理的方法:

  • TransactionTemplate

    TransactionalOperator

  • TransactionManager

    直接實作

Spring團隊通常建議對指令式流程中的程式設計式事務管理推薦使用

TransactionTemplate

,對響應性代碼推薦

TransactionalOperator

。第二種方法類似于使用

JTA

UserTransaction

API,盡管異常處理的麻煩程度較小。

1.5.1 使用

TransactionTemplate

TransactionTemplate

采用與其他Spring模闆(如

JdbcTemplate

)相同的方法。它使用一種回調方法(使應用程式代碼不必進行樣闆擷取和釋放事務性資源),并生成意向驅動的代碼,因為你的代碼僅專注于你要執行的操作。

如下面的示例所示,使用

TransactionTemplate

完全将你與Spring的事務基礎結構和api結合在一起。程式設計式事務管理是否适合你的開發需求是你必須自己做的決定。

必須在事務上下文中運作并且顯式使用

TransactionTemplate

的應用程式代碼類似于下一個示例。作為應用程式開發人員,你可以編寫

TransactionCallback

實作(通常表示為匿名内部類),其中包含你需要在事務上下文中運作的代碼。然後,你可以将自定義

TransactionCallback

的執行個體傳遞給

TransactionTemplate

上暴露的

execute(..)

方法。以下示例顯示了如何執行此操作:

public class SimpleService implements Service {

    // single TransactionTemplate shared amongst all methods in this instance
    private final TransactionTemplate transactionTemplate;

    // use constructor-injection to supply the PlatformTransactionManager
    public SimpleService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    public Object someServiceMethod() {
        return transactionTemplate.execute(new TransactionCallback() {
            // the code in this method runs in a transactional context
            public Object doInTransaction(TransactionStatus status) {
                updateOperation1();
                return resultOfUpdateOperation2();
            }
        });
    }
}           

如果沒有傳回值,則可以将便捷的

TransactionCallbackWithoutResult

類與匿名類一起使用,如下所示:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        updateOperation1();
        updateOperation2();
    }
});           

回調中的代碼可以通過在提供的

TransactionStatus

對象上調用

setRollbackOnly()

方法來復原事務,如下所示:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

    protected void doInTransactionWithoutResult(TransactionStatus status) {
        try {
            updateOperation1();
            updateOperation2();
        } catch (SomeBusinessException ex) {
            status.setRollbackOnly();
        }
    }
});           

指定事物配置

你可以通過程式設計方式或配置方式在

TransactionTemplate

上指定事務設定(例如傳播模式、隔離級别、逾時等)。預設情況下,

TransactionTemplate

執行個體具有預設的事務設定。以下示例顯示了針對特定

TransactionTemplate

的事務設定的程式設計自定義:

public class SimpleService implements Service {

    private final TransactionTemplate transactionTemplate;

    public SimpleService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);

        // the transaction settings can be set here explicitly if so desired
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        this.transactionTemplate.setTimeout(30); // 30 seconds
        // and so forth...
    }
}           

以下示例通過使用Spring XML配置來定義帶有一些自定義事務設定的

TransactionTemplate

<bean id="sharedTransactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
    <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
    <property name="timeout" value="30"/>
</bean>           

然後,你可以将

sharedTransactionTemplate

注入到所需的服務中。

最後,

TransactionTemplate

類的執行個體是線程安全的,因為這些執行個體不維護任何對話狀态。但是,

TransactionTemplate

執行個體确實會維護配置狀态。是以,盡管許多類可以共享一個

TransactionTemplate

執行個體,但是如果一個類需要使用具有不同設定(例如,不同的隔離級别)的

TransactionTemplate

,則需要建立兩個不同的

TransactionTemplate

執行個體。

參考代碼:

org.liyong.dataaccess.starter.TransactionTemplateIocContainer

1.5.2 使用

TransactionOperator

TransactionOperator

遵循類似于其他響應式操作符的設計。它使用一種回調方法(使應用程式代碼不必進行模版擷取和釋放事務性資源),并生成意向驅動的代碼,因為你的代碼僅專注于你要執行的操作。

如以下示例所示,使用

TransactionOperator

絕對可以使你與Spring的事務基礎結構和API結合。程式設計式事務管理是否适合你的開發需求是你必須自己做的決定。

TransactionOperator

的應用程式代碼類似于下一個示例:

public class SimpleService implements Service {

    // single TransactionOperator shared amongst all methods in this instance
    private final TransactionalOperator transactionalOperator;

    // use constructor-injection to supply the ReactiveTransactionManager
    public SimpleService(ReactiveTransactionManager transactionManager) {
        this.transactionOperator = TransactionalOperator.create(transactionManager);
    }

    public Mono<Object> someServiceMethod() {

        // the code in this method runs in a transactional context

        Mono<Object> update = updateOperation1();

        return update.then(resultOfUpdateOperation2).as(transactionalOperator::transactional);
    }
}           

TransactionalOperator

可以通過兩種方式使用:

  • 使用

    Reactor

    類型的操作符樣式(

    mono.as(transactionalOperator :: transactional)

    )
  • 其他所有情況的回調樣式(

    transactionalOperator.execute(TransactionCallback <T>)

ReactiveTransaction

setRollbackOnly()

transactionalOperator.execute(new TransactionCallback<>() {

    public Mono<Object> doInTransaction(ReactiveTransaction status) {
        return updateOperation1().then(updateOperation2)
                    .doOnError(SomeBusinessException.class, e -> status.setRollbackOnly());
        }
    }
});           

取消信号

在響應式流中,

Subscriber

可以取消其

Subscription

并停止其

Publisher

Project Reactor

以及其他庫中的操作符,例如

next()

take(long)

timeout(Duration)

等,都可以發出取消操作。沒有辦法知道取消的原因,無論是由于錯誤還是僅僅是出于進一步消費的興趣,并且在5.2版中,

TransactionalOperator

預設在取消時送出事務。在版本5.3中,這種行為将發生改變,事務将在取消時復原,以建立可靠的和确定性的結果。是以,重要的是要考慮從事務釋出伺服器下遊使用的操作符。特别是在

Flux

或其他多值

Publisher

的情況下,必須使用完整的輸出以允許事務完成。

你可以為

TransactionalOperator

指定事務設定(例如傳播模式、隔離級别、逾時等)。預設情況下,

TransactionalOperator

執行個體具有

預設的事務設定

。以下示例顯示了針對特定

TransactionalOperator

的事務設定的自定義:

public class SimpleService implements Service {

    private final TransactionalOperator transactionalOperator;

    public SimpleService(ReactiveTransactionManager transactionManager) {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();

        // the transaction settings can be set here explicitly if so desired
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        definition.setTimeout(30); // 30 seconds
        // and so forth...

        this.transactionalOperator = TransactionalOperator.create(transactionManager, definition);
    }
}           

1.5.3 使用

TransactionManager

以下各節說明指令式和響應式事務管理器的用法。

PlatformTransactionManager

對于指令式事務,可以直接使用

org.springframework.transaction.PlatformTransactionManager

來管理事務。為此,通過bean引用将你使用的

PlatformTransactionManager

的實作傳遞給bean。然後,通過使用

TransactionDefinition

TransactionStatus

對象,可以啟動事務、復原和送出。以下示例顯示了如何執行此操作:

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = txManager.getTransaction(def);
try {
    // put your business logic here
}
catch (MyException ex) {
    txManager.rollback(status);
    throw ex;
}
txManager.commit(status);           

ReactiveTransactionManager

使用響應式事務時,可以直接使用

org.springframework.transaction.ReactiveTransactionManager

來管理事務。為此,請通過bean引用将你使用的

ReactiveTransactionManager

TransactionDefinition

ReactiveTransaction

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

Mono<ReactiveTransaction> reactiveTx = txManager.getReactiveTransaction(def);

reactiveTx.flatMap(status -> {

    Mono<Object> tx = ...; // put your business logic here

    return tx.then(txManager.commit(status))
            .onErrorResume(ex -> txManager.rollback(status).then(Mono.error(ex)));
});           
  • TransactionTemplate

    TransactionalOperator

  • TransactionManager

TransactionTemplate

TransactionalOperator

JTA

UserTransaction

TransactionTemplate

TransactionTemplate

JdbcTemplate

TransactionTemplate

TransactionTemplate

TransactionCallback

TransactionCallback

TransactionTemplate

execute(..)

public class SimpleService implements Service {

    // single TransactionTemplate shared amongst all methods in this instance
    private final TransactionTemplate transactionTemplate;

    // use constructor-injection to supply the PlatformTransactionManager
    public SimpleService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    public Object someServiceMethod() {
        return transactionTemplate.execute(new TransactionCallback() {
            // the code in this method runs in a transactional context
            public Object doInTransaction(TransactionStatus status) {
                updateOperation1();
                return resultOfUpdateOperation2();
            }
        });
    }
}           

TransactionCallbackWithoutResult

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        updateOperation1();
        updateOperation2();
    }
});           

TransactionStatus

setRollbackOnly()

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

    protected void doInTransactionWithoutResult(TransactionStatus status) {
        try {
            updateOperation1();
            updateOperation2();
        } catch (SomeBusinessException ex) {
            status.setRollbackOnly();
        }
    }
});           

TransactionTemplate

TransactionTemplate

TransactionTemplate

public class SimpleService implements Service {

    private final TransactionTemplate transactionTemplate;

    public SimpleService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);

        // the transaction settings can be set here explicitly if so desired
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        this.transactionTemplate.setTimeout(30); // 30 seconds
        // and so forth...
    }
}           

TransactionTemplate

<bean id="sharedTransactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
    <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
    <property name="timeout" value="30"/>
</bean>           

sharedTransactionTemplate

TransactionTemplate

TransactionTemplate

TransactionTemplate

TransactionTemplate

TransactionTemplate

org.liyong.dataaccess.starter.TransactionTemplateIocContainer

TransactionOperator

TransactionOperator

TransactionOperator

TransactionOperator

public class SimpleService implements Service {

    // single TransactionOperator shared amongst all methods in this instance
    private final TransactionalOperator transactionalOperator;

    // use constructor-injection to supply the ReactiveTransactionManager
    public SimpleService(ReactiveTransactionManager transactionManager) {
        this.transactionOperator = TransactionalOperator.create(transactionManager);
    }

    public Mono<Object> someServiceMethod() {

        // the code in this method runs in a transactional context

        Mono<Object> update = updateOperation1();

        return update.then(resultOfUpdateOperation2).as(transactionalOperator::transactional);
    }
}           

TransactionalOperator

  • Reactor

    mono.as(transactionalOperator :: transactional)

  • transactionalOperator.execute(TransactionCallback <T>)

ReactiveTransaction

setRollbackOnly()

transactionalOperator.execute(new TransactionCallback<>() {

    public Mono<Object> doInTransaction(ReactiveTransaction status) {
        return updateOperation1().then(updateOperation2)
                    .doOnError(SomeBusinessException.class, e -> status.setRollbackOnly());
        }
    }
});           

Subscriber

Subscription

Publisher

Project Reactor

next()

take(long)

timeout(Duration)

TransactionalOperator

Flux

Publisher

TransactionalOperator

TransactionalOperator

TransactionalOperator

public class SimpleService implements Service {

    private final TransactionalOperator transactionalOperator;

    public SimpleService(ReactiveTransactionManager transactionManager) {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();

        // the transaction settings can be set here explicitly if so desired
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        definition.setTimeout(30); // 30 seconds
        // and so forth...

        this.transactionalOperator = TransactionalOperator.create(transactionManager, definition);
    }
}           

TransactionManager

PlatformTransactionManager

org.springframework.transaction.PlatformTransactionManager

PlatformTransactionManager

TransactionDefinition

TransactionStatus

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = txManager.getTransaction(def);
try {
    // put your business logic here
}
catch (MyException ex) {
    txManager.rollback(status);
    throw ex;
}
txManager.commit(status);           

ReactiveTransactionManager

org.springframework.transaction.ReactiveTransactionManager

ReactiveTransactionManager

TransactionDefinition

ReactiveTransaction

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

Mono<ReactiveTransaction> reactiveTx = txManager.getReactiveTransaction(def);

reactiveTx.flatMap(status -> {

    Mono<Object> tx = ...; // put your business logic here

    return tx.then(txManager.commit(status))
            .onErrorResume(ex -> txManager.rollback(status).then(Mono.error(ex)));
});           

作者

個人從事金融行業,就職過易極付、思建科技、某網約車平台等重慶一流技術團隊,目前就職于某銀行負責統一支付系統建設。自身對金融行業有強烈的愛好。同時也實踐大資料、資料存儲、自動化內建和部署、分布式微服務、響應式程式設計、人工智能等領域。同時也熱衷于技術分享創立公衆号和部落格站點對知識體系進行分享。關注公衆号:青年IT男 擷取最新技術文章推送!

部落格位址:

http://youngitman.tech

CSDN:

https://blog.csdn.net/liyong1028826685

微信公衆号:

Spring 5 中文解析資料存儲篇-程式設計式事物管理

技術交流群:

Spring 5 中文解析資料存儲篇-程式設計式事物管理