当前位置:网站首页>Unexpected rollback exception analysis and transaction propagation strategy for nested transactions
Unexpected rollback exception analysis and transaction propagation strategy for nested transactions
2022-07-25 12:12:00 【JackLi0812】
UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
1. Problem description and recurrence
jfoaProvidesAuditThe function of , The target method ( For example, add users ) Transaction management exists ,
stay Audit You need to query users ( Business management ), Finally, after the target method is executed Audit Insertion of records ( Business management ).
That is, add users ( Business ) Query users in ( Business ) Will throw an exception :
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
Literally means :
An unpredictable rollback exception occurred , Because the transaction has been flagged, it can only be rolled back , So the transaction rolled back .Now let's reproduce and describe this problem .
@Around("audit()")
public Object recordLog(ProceedingJoinPoint pjp) throws Throwable {
Log log = null;
Customer principal = null;
try {
// note1: Get the currently logged in user here , Note that this method can throw exceptions
// 1) getCurrentCustomer In transaction management
// 2) catch The method call did not continue to throw exceptions
principal = customerService.getCurrentCustomer();
} catch (Exception ignore) {
LOGGER.debug("Get principal error!", ignore);
}
// ... Omit some intermediate code
Object result;
try {
// note3: Specific objectives and methods
result = pjp.proceed();
}
catch(Throwable throwable) {
if(log != null) {
log.setMessage("Execute Failed: " + throwable.getMessage());
}
throw throwable;
}
finally {
// ...
}
return result;
}
// note2: The target method is transaction management
@Audit(ResourceEnum.Customer)
@Transactional
@Override
public Integer insertCustomer(@AuditObject("getName()") Customer user) {
if(isValid(user)) {
user.setPassword(
SecurityUtil.generatorPassword(user.getAccount(), user.getPassword()));
return customerDao.insert(user);
}
return null;
}
Pay attention to the above
note1andnote2, In this case, the exception of this article will appear .
2. Principle analysis
because spring Of
@TransactionalThe default transaction propagation strategy of annotation isPropagation.REQUIRED,
PROPAGATION_REQUIRED It means , There's business at the moment , Use the current transaction , If there is no transaction at present, create a transaction . therefore , When
When the target method is called , Because the target method has transactions , When the target method is called, the transaction will be opened ,
When executednote1when ,getCurrentCustomerMethods
There is a business , According to the transaction propagation strategy , spring Will use the transaction of the target method ,
howevergetCurrentCustomerYes try-catch Handle , alsocatchNo more transactions are thrown ,
So whengetCurrentCustomerWhen an exception is thrown , spring To execute rollback operation , however catch
Did not continue to throw exceptions , It will continue to be called untilnote3Continue to execute , When the target method is called
Because it is normal, the call is completed , Therefore, it is necessary to implement commit, So this exception will be thrown .
2.0 Introduction to transaction propagation strategy
spring The following communication strategies are defined :
public enum Propagation {
/** * There's business at the moment , Use the current transaction , If there is no transaction at present, create a transaction */
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
/** * Support current transaction , If it doesn't exist , To execute in a non transactional manner . * notes : For the transaction manager of transaction synchronization , It's a little different from having no business at all , * Because it defines the transaction scope to which synchronization will be applied . * result , Same resources (JDBC Connect 、Hibernate Conversation, etc ) * Will be shared for the entire specified range . Be careful , It depends. * The actual synchronization configuration of the transaction manager . */
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
/** * If the current is related to a transaction, the current transaction is used , If there is no transaction at present, an exception will be thrown . */
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
/** * Create a new transaction regardless of whether there is a current transaction . * If there is a current transaction, suspend the current transaction . */
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
/** * Run in a non transactional manner , If there is currently a transaction , Then suspend the current transaction */
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
/** * Run in a non transactional manner , If there is currently a transaction , Throw an exception */
NEVER(TransactionDefinition.PROPAGATION_NEVER),
/** * If the current transaction exists , Then execute... In a nested transaction , Otherwise, the behavior is similar {@code REQUIRED}. * Be careful : The actual creation of nested transactions only applies to specific transaction managers . * This only applies to JDBC DataSourceTransactionManager. * some JTA The provider may also support nested transactions . */
NESTED(TransactionDefinition.PROPAGATION_NESTED);
2.1 Default propagation policy
spring Of
@TransactionalThe default transaction propagation strategy of annotation isPropagation.REQUIRED
public @interface Transactional {
// ...
/** * The transaction propagation type. * <p>Defaults to {@link Propagation#REQUIRED}. * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior() */
Propagation propagation() default Propagation.REQUIRED;
2.2 The problem summary
When methodA call methodB, And both parties have affairs ( Transaction nesting ),
And the communication strategies arePropagation.REQUIREDwhen , It will lead to two methods
Share a transaction ,methodB Mark the transaction as rollback ,methodA in commit This business ,
Then it will appear that the transaction has been marked for rollback (methodB logo ) Exception information for .
3. resolvent
Know the cause of the problem , Naturally, I know the solution , But different business scenarios may have different solutions ,
You need to choose the right solution according to your business scenarios
3.1 modify try-catch
For internal methods methodB Don't go ahead try-catch perhaps catch Continue to throw exception .
3.2 Modify the transaction propagation strategy
- If you modify an external transaction methodA Transaction propagation strategy of , be methodA Only the transaction can be cancelled ( Generally not available ).
- Modify the interior methodB Transaction propagation strategy of , Generally, it can be changed to
REQUIRES_NEW,NOT_SUPPORTED,NESTED.NOT_SUPPORTEDConvert internal transactions into non transactional operations .REQUIRES_NEWWill create a new transaction run .NESTEDRun in nested transactions .
For example, the business scenario here , First is the need for transaction management , So I can use
REQUIRES_NEW,NESTED,
secondly , audit Records and ,getCurrentCustomerAt no time should it affect the operation of core business logic , therefore ,
Finally, I choose to modify the transaction propagation strategy asREQUIRES_NEWTo solve this problem . If your nested transaction is related to the main transaction ,
Then you should chooseNESTED.
Last , One more thing to note : In the same class , Transaction nesting is subject to the outermost method , Nested transactions fail ; Transactions nested in different classes will take effect ;

边栏推荐
- Median (二分答案 + 二分查找)
- 【GCN-RS】Region or Global? A Principle for Negative Sampling in Graph-based Recommendation (TKDE‘22)
- Application of comparative learning (lcgnn, videomoco, graphcl, XMC GaN)
- flink sql client 连接mysql报错异常,如何解决?
- 【GCN-CTR】DC-GNN: Decoupled GNN for Improving and Accelerating Large-Scale E-commerce Retrieval WWW22
- R语言可视化散点图、使用ggrepel包的geom_text_repel函数避免数据点之间的标签互相重叠(设置min.segment.length参数为Inf不添加标签线段)
- Solutions to the failure of winddowns planning task execution bat to execute PHP files
- 容错机制记录
- 【CTR】《Towards Universal Sequence Representation Learning for Recommender Systems》 (KDD‘22)
- 【AI4Code】《Contrastive Code Representation Learning》 (EMNLP 2021)
猜你喜欢

剑指 Offer 22. 链表中倒数第k个节点

Brpc source code analysis (VI) -- detailed explanation of basic socket

氢能创业大赛 | 国家能源局科技司副司长刘亚芳:构建高质量创新体系是我国氢能产业发展的核心

Power Bi -- these skills make the report more "compelling"“

NLP知识----pytorch,反向传播,预测型任务的一些小碎块笔记

GPT plus money (OpenAI CLIP,DALL-E)

Learning to Pre-train Graph Neural Networks(图预训练与微调差异)

Solutions to the failure of winddowns planning task execution bat to execute PHP files

给生活加点惊喜,做创意生活的原型设计师丨编程挑战赛 x 选手分享

brpc源码解析(四)—— Bthread机制
随机推荐
容错机制记录
【Debias】Model-Agnostic Counterfactual Reasoning for Eliminating Popularity Bias in RS(KDD‘21)
Figure neural network for recommending system problems (imp-gcn, lr-gcn)
Multi-Label Image Classification(多标签图像分类)
The applet image cannot display Base64 pictures. The solution is valid
Application of comparative learning (lcgnn, videomoco, graphcl, XMC GaN)
PHP one server sends pictures to another. Curl post file_ get_ Contents save pictures
【GCN-RS】Are Graph Augmentations Necessary? Simple Graph Contrastive Learning for RS (SIGIR‘22)
Go 垃圾回收器指南
[multimodal] transferrec: learning transferable recommendation from texture of modality feedback arXiv '22
Intelligent information retrieval(智能信息检索综述)
Brpc source code analysis (IV) -- bthread mechanism
Go garbage collector Guide
【GCN-RS】Are Graph Augmentations Necessary? Simple Graph Contrastive Learning for RS (SIGIR‘22)
Hydrogen entrepreneurship competition | Liu Yafang, deputy director of the science and Technology Department of the National Energy Administration: building a high-quality innovation system is the cor
小程序image 无法显示base64 图片 解决办法 有效
Ups and downs of Apple's supply chain in the past decade: foreign head teachers and their Chinese students
嵌套事务 UnexpectedRollbackException 分析与事务传播策略
[high concurrency] Why is the simpledateformat class thread safe? (six solutions are attached, which are recommended for collection)
客户端开放下载, 欢迎尝鲜