[hibernate java] transaction management tussen methods

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Goldme
  • Registratie: September 2000
  • Laatst online: 25-08 15:39
Momenteel ben ik Hibernate aan het implementeren voor een JSE applicatie (geen managed omgeving). Bij de design van de data access methods hik ik tegen de volgende situatie aan. Stel dat ik de volgende situatie heb.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
methodA()
{
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
... do work
session.getTransaction().commit();
}

methodB()
{
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
... do work
session.getTransaction().commit();
}


Zoals je ziet maak ik gebruik van een session die op thread level wordt aangeboden zodat ik de session niet hoef te managen. Op zich zouden beide methods individueel goed werken. Maar wat moet ik doen als ik een actie heb die atomair moet zijn en deze actie maakt roept methodA als methodB aan? Dus:

Java:
1
2
3
4
5
atomicMethod()
{
methodA();
methodB();
}


methodA EN methodB moeten ofwel beiden lukken of niet. Anders wil ik een rollback hebben. Dat is met de huidige code niet mogelijk zoals het hierboven staat. methodA is gecommit als methodB een rollback doet en kan je dus methodA niet meer rollbacken.

Ik kan in deze situatie methodB ook niet aanroepen vanaf methodA omdat methodB op een gegeven moment een rollback of een commit doet en dat zal de session ongeldig maken als ik daar verder mee wil gaan in methodA. Het ongeldig maken van de session gebeurt als je de session via getCurrentSession hebt.

Op zich zou ik de transaction management weg kunnen halen uit methodA en methodB en deze last bij de aanroepende partij leggen (atomicMethod). atomicMethod is in dit geval een business logic class die dus wel weet dat dit een atomaire actie moet zijn. methodA en methodB kunnen er dan vanuit gaan dat er een transaction lopende is en dat de currentSession goed is, ze hoeven ook nooit een commit of een rollback te doen aangezien de aanroepende partij bepaalt of hij tevreden is met het resultaat (methodA en methodB geven uiteraard daar feedback over). Moet ik de business logic echter wel lastig vallen met details over een transaction die open moet en aan het eind afgesloten moet worden? Die last wordt dan bij alle aanroepende partijen gelegd en dat maakt de data access methods wat minder toegankelijk.

Aangezien dit mijn eerste project met Hibernate is moet ik het inpassen van hibernate in het ontwerp nog onder de knie krijgen.

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Ik heb geen ervaring met de java hibernate versie, maar in nhibernate geeft BeginTransaction een Itransaction instance terug.Je zou een overloaded method kunnen aanmaken waarbij de overload een Itransaction accepteer. De overload zonder parameters creert voor zichzelf een transactie.

Een andere oplossing is misschien achterhalen of ISession de mogelijkheid heeft om de controleren of je je al in een sessie bevind. Zo niet, dan maak je alsnog een transactie aan.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Mr_Light
  • Registratie: Maart 2006
  • Niet online

Mr_Light

Zo-i-Zo de gekste.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
interface AtomicTask {
 void do();
}

class TransactionHandler() {
  public static void execute(AtomicTask task) {
   Session session = HibernateUtil.getSessionFactory().getCurrentSession();
   Transaction transaction = session.beginTransaction();
   task.do();
   transaction.commit();
 }
}

Dan word het met een static import zo iets:
Java:
1
2
3
4
5
6
 execute(new AtomicTask() {
  public void do() {
    methodA();
    methodB();
  }
 });

Er moet nog een catch bij waar je rolled back.

Het is maar een idee, voor de rest zit ik al een tijd aan het bier dus geen garanties - zo doende weet ik ook de naam niet van het 'pattern'. :z

Checken of er nog geen transactie is en alleen dan er een starten in de methoden kan ook handig zijn - echter zo als je ziet heb je dan wel overal code duplication enzo.

meuh bier. <+:)

IceManX schreef: sowieso


Acties:
  • 0 Henk 'm!

  • bat266
  • Registratie: Februari 2004
  • Laatst online: 24-08 06:41
Je zou ook eens kunnen kijken naar spring functionaliteit en @Transactional annotation. Nu weet ik eerlijk gezegd niet of die funtionaliteit alleen maar werkt in samenwerking met een Container in een server, Maar anders zou het voor jou een stuk makkelijker worden.

Better to remain silent and be thought a fool then to speak out and remove all doubt.


Acties:
  • 0 Henk 'm!

  • Goldme
  • Registratie: September 2000
  • Laatst online: 25-08 15:39
Ik heb toch maar besloten een JTA transaction model te implementeren met behulp van Bitronix TransactionManager aangezien dat geschikt is voor mijn situatie (data access wordt straks ook gebruikt binnen een AS en is JTA dus wel beschibaar).