
001/*- 002 * #%L 003 * HAPI FHIR Storage api 004 * %% 005 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.dao.tx; 021 022import ca.uhn.fhir.interceptor.model.RequestPartitionId; 023import ca.uhn.fhir.rest.api.server.RequestDetails; 024import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; 025import ca.uhn.fhir.util.ICallable; 026import org.springframework.transaction.annotation.Isolation; 027import org.springframework.transaction.annotation.Propagation; 028import org.springframework.transaction.support.TransactionCallback; 029 030import java.util.concurrent.Callable; 031import javax.annotation.Nonnull; 032import javax.annotation.Nullable; 033 034/** 035 * This class is used to execute code within the context of a database transaction, 036 * just like Spring's {@link org.springframework.transaction.support.TransactionTemplate} 037 * but with more functionality. It can auto-execute code upon rollback, it translates 038 * specific exceptions, and it stores transaction context in a ThreadLocal. 039 */ 040public interface IHapiTransactionService { 041 042 /** 043 * Fluent builder for creating a transactional callback 044 * <p> 045 * Method chain must end with a call to {@link IExecutionBuilder#execute(Runnable)} or one of the other 046 * overloads of <code>task(...)</code> 047 * </p> 048 */ 049 IExecutionBuilder withRequest(@Nullable RequestDetails theRequestDetails); 050 051 /** 052 * Fluent builder for internal system requests with no external 053 * requestdetails associated 054 */ 055 IExecutionBuilder withSystemRequest(); 056 057 /** 058 * Fluent builder for internal system requests with no external 059 * {@link RequestDetails} associated and a pre-specified partition ID. 060 * This method is sugar for 061 * <pre> 062 * withSystemRequest() 063 * .withRequestPartitionId(thePartitionId); 064 * </pre> 065 * 066 * @since 6.6.0 067 */ 068 default IExecutionBuilder withSystemRequestOnPartition(RequestPartitionId theRequestPartitionId) { 069 return withSystemRequest().withRequestPartitionId(theRequestPartitionId); 070 } 071 072 /** 073 * @deprecated It is highly recommended to use {@link #withRequest(RequestDetails)} instead of this method, for increased visibility. 074 */ 075 @Deprecated 076 <T> T withRequest( 077 @Nullable RequestDetails theRequestDetails, 078 @Nullable TransactionDetails theTransactionDetails, 079 @Nonnull Propagation thePropagation, 080 @Nonnull Isolation theIsolation, 081 @Nonnull ICallable<T> theCallback); 082 083 interface IExecutionBuilder { 084 085 IExecutionBuilder withIsolation(Isolation theIsolation); 086 087 IExecutionBuilder withTransactionDetails(TransactionDetails theTransactionDetails); 088 089 IExecutionBuilder withPropagation(Propagation thePropagation); 090 091 IExecutionBuilder withRequestPartitionId(RequestPartitionId theRequestPartitionId); 092 093 IExecutionBuilder readOnly(); 094 095 IExecutionBuilder onRollback(Runnable theOnRollback); 096 097 void execute(Runnable theTask); 098 099 <T> T execute(Callable<T> theTask); 100 101 <T> T execute(TransactionCallback<T> callback); 102 } 103}