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.techCSDN:
https://blog.csdn.net/liyong1028826685微信公衆号:

技術交流群: