Thursday, December 13, 2007

DataServiceTransaction & LCDS

Just a quick blog note on something that I've now wasted a good day on twice, only because I never blogged it last time. The challenge is say you need to make changes to data in a database, maybe across multiple tables, and using DataServices just doesn't make sense. For example, cloning x number of records. It's easy enough to create your Java remote objects and call them from Flex, but then in an FDS/LCDS implementation how do you push those changes out to Flex clients?

There's some documentation on this, scattered vaguely across the web, and there's a good chance that perhaps this has already been blogged - but I just couldn't find it. The trick is that there are 2 sides to this story, one, you must perform your operations on the database directly, and then two, you must INFORM FDS that changes have occurred. So say I want to create a new Author record, this is what that might look like:

public void createAuthor(){  
DataServiceTransaction dtx = DataServiceTransaction.begin(false);
//create record and save:
Author auth = new Author();
auth.setFirstName("Ernest");
auth.setLastName("Hemingway");
AuthorDAO dao = new AuthorDAO();
dao.create(auth);
//let LCDS know:
dtx.createItem("author", auth);
dtx.commit();
}
So I just do my regular db insert, then I use a DataServiceTransaction to let FDS know that I've created an Item. Alternatively, I could use this approach:
public void createFDSItem(){
DataServiceTransaction dtx = DataServiceTransaction.begin(false);
Author auth = new Author();
auth.setFirstName("victor");
auth.setLastName("javarubba");
AuthorDAO dao = new AuthorDAO();
dao.create(auth);
dtx.refreshFill("author", null);
dtx.commit();
}
This approach might be a bit of overkill and might be better suited when doing mass updates across many records. I did a little bit of testing and it seemed that for the most part calling CreateItem() was faster that the refreshFill() in pushing the new record to the Flex Client.

What cost me so much grief is that I was falsely led down the garden path to believe that calling dtx.createItem("author", auth) would not only inform FDS but also actually create the item. This is not the case. There! Officially blogged!

11 comments:

rjb said...

Hi Vic,
Since I'm new to Flex and FDS now LCDS, I may be a bit ignorant with my question but here goes: Is there a way to push data changes to a Flex client if say a server side application updates or does an insert to the database? It seems like this scenario only works if you have more than one Flex client doing updates while the other Flex clients respond.

Victor Rubba said...

Couple things you can do here. You could use messaging and push out a new object or updated object from pretty much any where to any listening flex client. That's the easiest way and will soon be free with the release of BlazeDS. If you're lucky enough to have access to LCDS, then you could tap into FlexSession and tell FDS directly what collections or items have been updated and it will sync any clients "looking" at those items/collections. A key thing to note, your server side will do the updating against the db, you cannot force FDS to do that for you, however you can tell FDS what has changed.

codecraig said...

I have a Java thread running that collects some statistics, and I'd like to send the results to Flex...how can I do this without Flex asking for them?

Vic Rubba said...

Use Java messaging to push messages into a queue, then use the LCDS JMS adapter to subscribe to that queue and push those messages out to subscribed Flex clients. That would probably be the easiest approach.

Anonymous said...

Hi Victor,
I am new for LCDS. I want to do update my array collection when my MySQL get update/insert from outside to flex application. How can i notify my Flex client about this update or insert at Database side. If you have any example then please let me know, it will very helpful to me.

Vic Rubba said...

A fairly common question is how do you let FDS/LCDS know when you've made changes outside of the LCDS world, so that it will update on your flex client. I was going to do a blog entry on this but after a quick search, this posting http://flex.blogs2k.com/2007/12/13/dataservicetransaction-lcds/ pretty much explains it. Do what you need to against the DB and then use DataServiceTransaction to inform LCDS what has changed. This works quite well.

Anonymous said...

Could you please post a blog on "how do you let FDS/LCDS know when you've made changes outside of the LCDS world". Because the link you have provided is not working.

Vic Rubba said...

crazedEntry m_Entry = new crazedEntry();
m_Entry.setcrazedMember(crazedMember);
m_Entry.setcrazedSession(crazedSession);
m_Entry.setMessage(msgText);
m_Entry.setTimestamp(new Date());
session.beginTransaction();
session.saveOrUpdate(m_Entry);
//this commits the record to the db
session.getTransaction().commit();
//these next 3 lines only serve to notify Data Services and clients of what has happened
//it does not update the db!!!
DataServiceTransaction dtx = DataServiceTransaction.begin(true);
dtx.createItem("crazed.Entry", m_Entry);
dtx.commit();

Anonymous said...

Hi Vic,

If I have an external application to update the Database, this external application reside different box and outside the app server, totally unrelated to the Flex application except share the same Database. How can I push the data to those Flex clients whenever the Database got updated? How does polling-amf work? Does it work for publish/subscribe only? I tried to use the polling-amf as the channel to do fill. But it does not work for me.

Vic Rubba said...

Polling-amf etc is a pseudo push mechanism... you can set the interval to poll in your config files and essentially it means Flex will initiate communication with Java every x seconds. It has nothing really to do with what happens under the hood of LCDS. If you can, setup messaging between your app server and the LCDS server, which will pass data change notifications and then use the code above to force LCDS to notify the user.

Anonymous said...

Hi Vic,

Thanks for the quick apply. I have another issue. Our external batch java application is updating some tables, and then a trigger/StoreProcedure will update those tables which Flex clients are interested in.

Can LCDS listen to DB table changes, and then push to the Flex clients?

I knew if we want to use the approach you have suggested, we can, but Just feel why another application (another team) will change their architecture/extra work to help us out.