gpt4 book ai didi

java - 如何知道回滚已经执行了? [@交易]

转载 作者:行者123 更新时间:2023-12-02 02:14:51 28 4
gpt4 key购买 nike

我有以下情况:

我正在迭代我的Affiliate 实体,对于每个实体,我需要在一个唯一的事务中保存和更新数据。因此,我有一个服务,其方法用 Spring @Transactional 注释(其中创建和更新数据)进行注释,但我不知道如何才能看到关联公司的事务已回滚?

我想知道对于特殊的附属机构,交易已回滚并从我的服务中检索自定义错误代码。

这是我在使用 Spring 之前的服务:

public void savePostingPaymentDetails(List<Posting> postingsToUpdate, List<PaymentPostingDetail> detailsToInsert, Payment payment) {
logger.info("DB ACCESS : INSERT PAYMENT DETAILS & UPDATE POSTINGS");
long begin = System.nanoTime();

this.em.getTransaction().begin();

try {
// TEST
// 1 - Save Payments
this.em.persist(payment);

// 2 - Save Details
for (PaymentPostingDetail ppd : detailsToInsert) {
this.em.persist(ppd);
}

// 3 - Update Postings
for (Posting p : postingsToUpdate) {
if(p.getSignature() != null)
{
p.getSignature().setModification("withholding-tax.pay", new Date());
}
else
{
logger.error("The Posting with id = " + p.getIdentifier() + " has no PersistenceSignature ?!");
}
this.em.merge(p);
}
}
catch (Exception e)
{
logger.error("Unexpected error on saving/updating the DB.", e);

this.em.getTransaction().rollback();
logger.info("RollBack done.");

e.printStackTrace();
System.exit(JobStatus.ABNORMAL_END_OF_EXECUTION_ERROR.getCode());
}

this.em.getTransaction().commit();
logger.info("Details inserted & Postings updated.");

long end = System.nanoTime();
logger.info("Execution time = " + ((end-begin) / 1000000) + " milliseconds.");
logger.info("----------------------------------------------------------");
}

现在我有这个:

@Transactional
public void savePostingPaymentDetails(List<Posting> postings, List<PaymentPostingDetail> paymentDetails, Payment payment)
{
logger.info("DB ACCESS : INSERT PAYMENT DETAILS & UPDATE POSTINGS");
long begin = System.nanoTime();

this.paymentRepository.save(payment);
this.ppdRepository.save(paymentDetails);

for(Posting p : postings){
if(p.getSignature() != null)
{
p.getSignature().setModifiedAt(LocalDate.now());
p.getSignature().setModifiedBy(PayCopyrightWithholdingTaxProcess.SIGNATURE);
}
else{
p.setSignature(new PersistenceSignature(LocalDate.now(), PayCopyrightWithholdingTaxProcess.SIGNATURE));
}
this.postingRepository.save(p);
}

long end = System.nanoTime();
logger.info("Execution time = " + ((end-begin) / 1000000) + " milliseconds.");
logger.info("----------------------------------------------------------");
}

但是如果事务已回滚,我如何返回一个特殊的整数(而不是 System.exit())?

最佳答案

有一种叫做用户管理事务(UMT)和容器管理事务(CMT)的东西当您使用 @Transactional 时,您实际上是将事务管理委托(delegate)给 Spring 容器(CMT),它负责为您打开和关闭事务等。它当抛出 unchecked Exception (如 NullPointerExceptionRuntimeException )时,会自动回滚。对于已检查的您必须指定何时发生回滚的异常@Transactional(rollbackFor=myCheckedException.class)

您还可以使用 TransactionalEventListener 监听、观察事务的执行情况,并使用一些 AOP 监听代码使用react,如 here 所示。 。但你最终并没有管理事务,Spring 正在为你做。当发生特殊情况时,客户端代码无法对某些自定义代码使用react,因为事务的管理已委托(delegate)给 Spring。

因此,您必须依靠用户管理的事务,在其中打开事务、提交事务并在回滚时使用react。这正是 UMT 的目的:完全控制您的交易

从你的旧代码中你可能会得到类似的东西:

public int savePostingPaymentDetails(List<Posting> postingsToUpdate, List<PaymentPostingDetail> detailsToInsert, Payment payment) {

int returnCode = 1 // 1 -> "success" , 0 -> "failure"

logger.info("DB ACCESS : INSERT PAYMENT DETAILS & UPDATE POSTINGS");
long begin = System.nanoTime();
long end = 0;

this.em.getTransaction().begin();

try {
// TEST
// 1 - Save Payments
this.em.persist(payment);

// 2 - Save Details
for (PaymentPostingDetail ppd : detailsToInsert) {
this.em.persist(ppd);
}

// 3 - Update Postings
for (Posting p : postingsToUpdate) {
if(p.getSignature() != null)
{
p.getSignature().setModification("withholding-tax.pay", new Date());
}
else
{
logger.error("The Posting with id = " + p.getIdentifier() + " has no PersistenceSignature ?!");
}
this.em.merge(p);
}
this.em.getTransaction().commit();
end = System.nanoTime();
}
catch (Exception e)
{
returnCode = 0;
logger.error("Unexpected error on saving/updating the DB.", e);

this.em.getTransaction().rollback();
logger.info("RollBack done.");

// e.printStackTrace();
System.exit(JobStatus.ABNORMAL_END_OF_EXECUTION_ERROR.getCode());
return returnCode;
}

//this.em.getTransaction().commit();
logger.info("Details inserted & Postings updated.");

//long end = System.nanoTime();
logger.info("Execution time = " + ((end-begin) / 1000000) + " milliseconds.");
logger.info("----------------------------------------------------------");
return returnCode = 1;
}

PS:顺便说一句,最佳实践是在提交失败时抛出异常,而不是特殊代码。

您的新方法签名可能是:

public void savePostingPaymentDetails(List<Posting> postingsToUpdate, List<PaymentPostingDetail> detailsToInsert, Payment payment) 
throws MyFailedDbOperationException, OtherException {

}

并在 catch block 上抛出异常

catch (Exception e)
{
logger.error("Unexpected error on saving/updating the DB.", e);

this.em.getTransaction().rollback();

logger.info("RollBack done.");
throw MyFailedDbOperationException("my db operation failed");
}

关于java - 如何知道回滚已经执行了? [@交易],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49445666/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com