トランザクション エラーの問題
ロールバック専用としてマークされているため、ロールバックされたトランザクションのエラー分析
トランザクションを使用して、削除操作を実行するときにエラーを報告します. エラーメッセージは次のとおりです
.
コード分析
呼び出しコードは次のとおりです。ビジネス ロジックを簡単に説明します。データベース エンティティには注文単位があるため、データベースを削除する場合は、最初に注文単位を削除し、削除が成功した後にデータベースを削除する必要があります。
@Override
public boolean delete(Long id) {
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(TransactionDefinition.withDefaults());
int result = 0;
try {
//-------------业务逻辑开始-------------
//删除订购单元
List<EbookCollectionUnitBean> collectionUnitBeans = ebookCollectionUnitMapper.selectList(Wrappers.<EbookCollectionUnitBean>lambdaQuery()
.eq(EbookCollectionUnitBean::getEbookCollectionId, id));
if (CollectionUtils.isNotEmpty(collectionUnitBeans)) {
collectionUnitBeans.stream().forEach(x -> eBookCollectionUnitService.delete(x.getId()));
}
//删除数据库
result = ebookCollectionMapper.deleteById(id);
//-------------业务逻辑结束-------------
//事务提交
dataSourceTransactionManager.commit(transactionStatus);
} catch (Exception e) {
dataSourceTransactionManager.rollback(transactionStatus);
e.printStackTrace();
throw new BusinessException(e.getMessage());
}
return result > 0;
}
上記のビジネス コードでは、注文ユニットを削除するプログラムを呼び出します: eBookCollectionUnitService.delete(x.getId()))
@Override
public Boolean delete(Long id) {
boolean result = false;
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(TransactionDefinition.withDefaults());
try {
EbookCollectionUnitBean ebookCollectionUnitBean = ebookCollectionUnitMapper.selectById(id);
/**
* 如果 数字资源采购库 的收录时间修改,则更改所属期刊下的所有文章 标记为馆藏资源
*/
if (ebookCollectionUnitBean.getPurchaseFlag() == 1) {
updateUnitPaperSource(ebookCollectionUnitBean, null);
}
result = ebookCollectionUnitMapper.deleteById(id) > 0;
dataSourceTransactionManager.commit(transactionStatus);
} catch (Exception e) {
log.error("===delete error info", e);
dataSourceTransactionManager.rollback(transactionStatus);
}
return result;
}
問題分析
直接的に言えば、2 番目の段落のコードは、データベースの更新時にエラーを報告し、トランザクションがロールバックされました。
コードの最初の部分のトランザクションが実行される
dataSourceTransactionManager.commit(transactionStatus);
と、それが見つかります
ロールバック専用としてマークされているため、トランザクションはロールバックされました(トランザクションは既にロールバック状態です) ロールバック専用としてマークされているため、選択クエリしか実行できず、挿入/更新/削除操作をロールバックする必要があります.このとき、トランザクションコミットの実行は必然的にエラーを報告するため、catch によってキャッチされ、同時に
catch
dataSourceTransactionManager.commit(transactionStatus);
にトランザクション ロールバック コードも含まれている
dataSourceTransactionManager.rollback(transactionStatus);
ため、2 番目のエラーがトリガーされます。
トランザクションは既に完了しています - commit や rollback をトランザクションごとに複数回呼び出さないでください(コミットまたはロールバックをトランザクションごとに複数回呼び出さないでください)
問題が解決しました
2 番目のコードで報告されたエラーが原因で、トランザクションがロールバックされていることがわかります。事業コードこれで問題は解決します。この時点で、呼び出しがエラーを報告しない場合、最初のコードはトランザクションを正常に送信でき、2 番目のエラー レポートはそれに応じて解決されます。