Az mf4php használata során szembesültem a fenti problémával. Ugye arra lenne szükség, hogy az üzenet akkor, és csak akkor kerüljön elküldésre, ha a commit sikeres. Ha a tranzakción kívül küldök üzenetet, akkor amennyiben az üzenet küldés sikertelen, a tranzakció nem rollbackelődik. Viszont ha tranzakción belülre teszem, akkor az üzenet elmegy függetlenül attól, hogy végeredményben sikeres-e a tranzakció, vagy sem. Feloldhatatlan problémának látszik, legalábbis nekem annak tűnt.
Fény az alagút végén
Kis utánaolvasás (JMS), után arra jutottam, hogy az üzeneteket tranzakción belül elküldöm, viszont azokat az mf4php szintjén várakoztatom. Sikeres commit után pedig ténylegesen elküldöm őket. Egy dolog húzhatja keresztbe a számításaimat, mégpedig ha ez a tényleges küldés okoz hibát. Erre viszont azt mondom, hogy ez már nem alkalmazás hiba, tehát nem is ott kell kezelni.
A megvalósításhoz egy dologra van szükség: az mf4php implementációnak értesülnie kell a sikeres commitról. Úgyhogy fogtam magam, és bevetettem a jó öreg observer mintát. Készítettem egy ObservableTransactionManager interfészt a trf4php-ben, ami értesíti a tranzakciós lépésekről a regisztrált megfigyelőket. Ezen kívül pedig létrehoztam egy TransactedMessageDispatcher absztrakt osztályt, ami képes a fent említett üzenetgyűjtésre és -elküldésre.
Használat
Nagyon egyszerű, egy dologra kell figyelni. Ugyanazt a tranzakció managert adjuk át az üzenet kezelőnek, mint amit ténylegesen tranzakció kezelésre használunk. Az alábbi példában a TransactedMemoryMessageDispatcher szerepel, ez egy egyszerű, memória alapú (szinkron) megvalósítása a fentieknek, azonban a beanstalk implementáció is támogatja mindezt.
|
|
Szívesen várom az észrevételeket/javaslatokat akár az elméletet, akár a megvalósítást illetően.