Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Info
titleDobre praktyki

Zaleca się stosowanie adnotacji do zarządzania transakcjami w klasach oznaczonych adnotacją @Service


W klasach, które nie są zarządzane przez kontekst aplikacji możemy wywoływać nasze bloki kodu również wewnątrz jednej transakcji wykorzystując do tego odpowiednie metody wrappujące z klasy TransactionWrapper (od wersji 3.2.76). We wcześniejszych wersjach należy skorzystać bezpośrednio z TransactionTemplate.


Tip

Należy pamiętać, że wszystkie operacje związane z bazą danych, które wykonujemy w danym zadaniu, powinny odbywać się wewnątrz jednej transakcji. Dzięki temu nasz kod będzie transakcyjny oraz będzie się szybciej wykonywać.


Przykłady użycia z wykorzystaniem adnotacji

Code Block
languagejava
titleWykonanie kilku operacj w jednej transakcji
@Service
public class CustomServiceImpl
    implements CustomService
{
	@Autowired
    private StructureService structureService;

    @Transactional
    public void addPositionAndOu()
    {
        Position p = new Position( "name", "symbol" );
        OrganizationalUnit ou = new OrganizationalUnit();
        ou.setName( "name" );
        ou.setSymbol( "symbol" );
        structureService.createPosition( p );
        structureService.createOrganizationalUnit( ou );
    }

    public void addPositionAndOuNonTransactional()
    {
        Position p = new Position( "name", "symbol" );
        OrganizationalUnit ou = new OrganizationalUnit();
        ou.setName( "name" );
        ou.setSymbol( "symbol" );
        structureService.createPosition( p );
        structureService.createOrganizationalUnit( ou );
    }
}

W powyższym przykładzie funkcja bez adnotacji @Transactional utworzy osobne transakcje dla każdej funkcji save, natomiast w funkcji oznaczonej @Transactional obie operacje będą działać na jednej tej samej transakcji.

 

Manualne zarządzanie transakcjami

Jeżeli potrzebujemy wykonać blok kodu wewnątrz aktywnej transakcji hibernate lub sharkowej oraz mieć dostęp do sesji i transakcji, to należy skorzystać z klasy TransactionWrapper.

 

public static void execute()
Code Block
languagejava
titlePobranie własnego serwisu w zadaniu automatycznym
Wykonie operacji wewnątrz transakcji hibernate
TransactionWrapper.get().doInHibernateTransaction( ( session ) -> {
    QueryExecutor qe = ComponentFactory.getQueryExecutor();
    {SQLQuery sql = qe.createSQLQuery( ... );
   ClientService cs = SpringContext.getBean( ClientService.class );
		cs.addPositionAndOu();
    }

...

...
    sql.executeUpdate();
});

 

Code Block
languagejava
titleWykonie operacji wewnątrz transakcji sharkowej
TransactionWrapper.get().doInSharkTransaction( ( sharkTransaction ) -> {
    ActivityService activityService = ServiceFactory.getActivityService();
	Map<String, Object> activityContext = activityService.getActivityContext( processId, activityId );
	activityContext.put( "id_zmiennej", "nowa_wartość" );
	activityService.setActivityContext( processId, activityId, activityContext );
});

Nasz kod może zwracać dowolny wynik.

Manualne zarządzanie transakcjami poniżej wersji 3.2.76

Istnieje możliwość manualnego zarządzania transakcjami w przypadkach gdy potrzebujemy większej kontroli lub potrzebujemy ich w obszarze kodu, w którym nie mamy możliwości skorzystania z adnotacji opisanych powyżej.

...