[Design of Messaging on JBoss (Messaging/JBoss)] - Re: XA recovery integration
by juha@jboss.org
"timfox" wrote : So to clarify, we should be doing something like the following:
|
| On server startup it should look in the db for any prepared tx states.
|
|
Why should we do this at startup? The tx coordinator is driving the recovery, no? It will eventually find transactions that ought to have been terminated still in its logs in prepared state. This is done by the periodic tasks in JBossTS. Once this event occurs, JBossTS first initiates its integration layer (XAResourceRecovery) to obtain the XAResource references and then drives it via recovery() calls. At that point we need to go look into our message persistent state and find if we need to drive the prepared transactions to termination.
This is how I understood how JBossTS manages things. Granted, I'm not done with the integration layer yet so I haven't been able to confirm this understanding to actual implementation, and may yet to be proven wrong.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3988228#3988228
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3988228
19 years, 4 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: XA recovery integration
by juha@jboss.org
"timfox" wrote :
| One thing I'm confused about, is I can see the prepared transaction ids being loaded at server peer startup into the transaction repository and I can see TransactionRepository::getPreparedTransactions returning a list of ids, but I can't see anywhere where the actual transactional state (i.e. the adds/acks) are being loaded from the database and "replayed" into the channel.
|
Can you explain what you mean by replayed into the channel in terms of API calls?
The handling of acks and references that I was able to extract from the submitted patch are below.
| public List getPreparedTransactions()
| {
|
| ArrayList prepared = new ArrayList();
|
| Iterator iter = globalToLocalMap.values().iterator();
|
| while (iter.hasNext())
| {
| Transaction tx = (Transaction) iter.next();
|
| try
| {
| if(trace)
| log.trace("Loading and handling refs and acks to the Tx "+tx);
|
| // TODO: [JPL] should this only apply to STATE_PREPARED transactions?
|
| handleReferences(tx, tx.getId());
| handleAcks(tx, tx.getId());
| }
| catch (Exception e)
| {
| // TODO: [JPL] fix this
| e.printStackTrace();
| }
|
| if (tx.xid != null && tx.getState() == Transaction.STATE_PREPARED)
| {
| prepared.add(tx.getXid());
| }
| }
|
| return prepared;
| }
|
|
| ...
|
|
| /**
| * Load the references and invoke the channel to handle those refs
| */
| private void handleReferences(Transaction tx, long txId) throws Exception {
|
| long messageId = persistenceManager.getMessageIdForRef(txId);
|
| List refsList = getRefs(messageId);
|
| // now we got all the refs
| // for each ref loaded, we'll invoke channel.handle
| for (Iterator iter = refsList.iterator(); iter.hasNext();)
| {
| CoreDestination d = getChannel(persistenceManager.getChannelId(txId), txId);
|
| if (trace)
| log.trace("Handling the channel");
|
| d.handle(null, (MessageReference) iter.next(), tx);
| }
| }
|
| /**
| * Load the acks and acknowledge them
| */
| private void handleAcks(Transaction tx, long txId) throws Exception {
|
| long messageId = persistenceManager.getMessageIdForAck(txId);
|
| List refsList = getRefs(messageId);
|
| for (Iterator iter = refsList.iterator(); iter.hasNext();)
| {
| Delivery del = new SimpleDelivery(null, (MessageReference) iter.next());
|
| try
| {
| if(trace)
| log.trace("Acknowledging..");
|
| ((DeliveryObserver)del).acknowledge(del, tx);
| }
| catch (Throwable e)
| {
| // TODO: [JPL] fix this
| e.printStackTrace();
| }
| }
| }
|
| /**
| * Get the message references based on the messageId from database
| */
| private List getRefs(long messageId) throws Exception
| {
| List noRefsList = new ArrayList();
| List refsList = new ArrayList();
|
| // Find the message store
| // TODO: [JPL] this needs to be fixed to go through the kernel
| MessageStore ms = getMessageStore();
|
| // and message reference from store
| MessageReference ref = ms.reference(messageId);
|
| // Store, sometime, does'nt know about the message referece
| // and the above ref may be null. Hence we need to load actual message
| // by goind back to the database and loading them based on id
|
| if (ref == null)
| {
| noRefsList.add(new Long(messageId));
| }
| else
| {
| refsList.add(ref);
| }
|
| // ask the pm to get the messages from messageId list
| List messagesList = persistenceManager.getMessages(noRefsList);
|
| for (Iterator iter = messagesList.iterator(); iter.hasNext();)
| {
| Message m = (Message) iter.next();
| MessageReference r = ms.reference(m);
| refsList.add(r);
| }
|
| return refsList;
| }
|
|
|
"timfox" wrote :
|
| I can also see the code Madhu supplied to do this has been removed. What am I missing here?
|
|
There should be no code removed. The only thing is some additions may have accidentally been omitted due to trying to extract a working patch from the multiple submissions. Let me know if something obvious is missing.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3988227#3988227
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3988227
19 years, 4 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: XA recovery integration
by timfox
So to clarify, we should be doing something like the following:
On server startup it should look in the db for any prepared tx states.
These should be then be loaded into the transaction repository.
We also need to load the state for these, i.e. "replay" the transaction through the channel.
This should be done by recreating acks/refs for that transaction, and basically just sending or acking them transactionally against the channel.
This will result in the correct tx callbacks being created on the tx.
Then if the recover() is called from the client on the XAResource, the corresponding ids should be returned, and an entry should be added in the client resource manager (TXState) for each prepared tx (if they don't already exist)
That's basically it.
Some of the above could be done lazily (i.e. don't reload prepared states until recover() is called), but the basic principle is the same.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3988194#3988194
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3988194
19 years, 4 months
[Design of JBoss Portal] - Re: Sub navigations in Jboss portals
by kvmkreddy
Hi,
You can just look at the Test portlet (came with jboss-portal itself). The actuall navigation was shown in the CatelogPortlet(which will comes with the jboss-portal).
Basically you need to define your *-object.xml such that it has the embedead tages(See the template below).
| <deployments>
| <deployment>
| <if-exists>overwrite</if-exists>
| <parent-ref>default</parent-ref>
| <page>
| <page-name> ROOT_NAV_1</page-name>
| <window>
| </window>
| <page>
| <page-name>SUB_NAV_1</page-name>
| </page>
| <page>
| <page-name>SUB_NAV_2</page-name>
| </page>
| </page>
| </deployment>
| </deployments>
|
|
I used to get the navigation as was implemented in the Test Portlet and able to display these links as navigation items in the lefthandseide(in CatelogPortlet) in my portal based on the Roles.
Thanks and Regards
Murali Reddy
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3988183#3988183
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3988183
19 years, 4 months