我有一个非事务方法调用事务方法,然后在事务方法执行后抛出 RuntimeException。
这是我的代码结构:
验证代码服务:
public void callingMethod(){
///some logic
if (codeReceivedFromUser != codeStoredInDB){
codeDTO.setNoOfRetries (codeDTO.setNoOfRetries() -1 );
codeRepository.update(codeDTO);
throw new RuntimeException(CodeError.CDE1);
}
}
代码库:
public class CodeRepository extends SuperRepository <Code, Integer>{
@Transactional
public codeDTO update (codeDTO dto){
///some logic
super.merge(TransformDTOToEntity(dto));
return dto;
}
}
超级存储库:
public class SuperRepository{
@Transactional
public void merge(T entity){
getEm.merge(entity);
getEm.flush();
}
}
当我检查日志时,我可以看到查询已刷新,但错误日志立即出现,没有提交:
休眠刷新
[我的更新查询]
记录错误
[我的代码错误.CDE1]
我想指出的是,我还从另一个没有抛出错误的非事务方法调用 CodeRepository.update,并且更新按预期提交。
该通话的日志如下所示
休眠刷新
[我的更新查询]
休眠提交
JDBC 提交
问题: 为什么在callingMethod中抛出RuntimeException后事务没有提交,而在其他情况下可以成功提交?如何确保在引发异常之前提交更新?
这是一种奇怪的行为。我会尝试通过注入 jakarta.transaction.UserTransaction (而不是使用 @Transactional 注释)来手动提交事务。
你可以尝试这样的事情:
import jakarta.transaction.UserTransaction;
public class CodeRepository extends SuperRepository <Code, Integer>{
@Inject
UserTransaction transaction;
@Transactional
public codeDTO update (codeDTO dto){
///some logic
try{
transaction.begin();
super.merge(TransformDTOToEntity(dto));
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
}
return dto;
}
}