Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Disconnected Remote Issues

Status
Not open for further replies.

VB400

Programmer
Sep 8, 1999
359
US
<br>
This is an issue that started in an earlier thread (probably the best thread I've seen so far). The issue is what happens when in a multi-tier environment, the front-end (client workstation) is disconnected from the Data-Tier (Application Server). We would like to keep the application running so that we're not losing valuable business while communication lines are down. <br>
<br>
If you have any experience or thoughts on this issue, please feel free to post them so others can learn.<br>
<br>
Thanks!
 
<br>
Steve Meier,<br>
<br>
... Continued from another thread<br>
<br>
Obviously, some part of your application will need to know whether to get the data from the &quot;central&quot; database or from the &quot;temporary local&quot; database. In which tier will this take place?<br>
<br>
You're definitely closer to it than I'm but how about generating the unique id at the time you sync -- you wouldn't need to check out any numbers!<br>
<br>
Thanks!<br>

 
VB400,<br>
<br>
Funny that you mention that because that was my first thought. Just resolve the issue when you sync the two together. However this brought up a valid discussion that went something like this:<br>
<br>
The field personnel log an incident report from a caller. The caller is given an incident number (not from the pool of numbers checked out) and their account is serviced. At the time of syncing to the master, the number is changed so now there is no reference of the incident number.<br>
<br>
You can get around this a couple of ways. One way is to check the numbers out prior to going on the road, or not use a primary key as the incident number. If you don't use the PK as the incident number, then you have to have some way of uniquely generating a key, based on the specific machine. Maybe use the name of the machine for the ID, however that makes for funny incident report numbers.<br>
<br>
In the case where the ID is unimportant, I feel that your proposed solution would be feasible.<br>
<br>
As far as saving the data, MS-Access with a similar scaled down schema as the master would have to reside on the users machine. The only problem with this is that now you have to setup ODBC DSN's or move your Data Centric layer to the users machine. I'm just thinking out loud here.<br>
<br>
Since we haven't gotten to this phase of the project yet, all these ideas are speculative. If you come up with something better than that, let me know since a lot of this is just theory that hasn't been tested.<br>
<br>
<br>
Steve<br>
<A HREF="mailto:sdmeier@jcn1.com">sdmeier@jcn1.com</A>
 
VB400,<br>
<br>
I was wondering, are you inserting new data into your database or are you amending existing records? If you are inserting new records have you thought about using disconnected recordsets? <br>
<br>
Open a connection to your original source when connected. Then break the connection by setting actriveconnection = nothing. Write the recordset to the hard drive. Then when your guys go out on site open the recordset from the harddrive start inserting and close the recordset (by saving to hard drive again.<br>
<br>
When the guys are back in the office again they can update the live database from their disconnect recordset. There are a few problems with this, ie unique identifiers - but the unique ID doesn't have to be an autonumber.<br>
<br>
If you are looking for code I can post it here.<br>
<br>
Cal
 
Cal,<br>
<br>
Sure, go ahead and post the code if you'd like. Who knows what might come of it. In our project, we did use the PK as the ID for the entity. However, it has several Foreign keys in many other related tables. We would be inserting new records and amending current ones. This makes things a little more tricky. I'd still like to look at the code though. Thanks for the offer!<br>
<br>
Steve<br>
<A HREF="mailto:sdmeier@jcn1.com">sdmeier@jcn1.com</A>
 
Hi Steve,<br>
<br>
It sounds to me like you're on the right track.<br>
<br>
In earlier posts in the other thread, I mentioned that we use a Proxy tier that resides on the user's desktop and acts as a messenger between the Data-Centric and UI-Centric tiers. All it does (initially) is receive the request from the UI-Centric object and route the request to the Data-Centric counterpart and vice-versa. This Proxy tier also acts as a data caching &quot;server&quot;.<br>
<br>
This tier can also be used to call a &quot;local version&quot; of the Data-Centric tier. For example,<br>
<br>
If ConnectionIsAlive then<br>
Set mobjPersist = CreateObject(&quot;MainDB.MyObjectPersist&quot;, SERVERNAME)<br>
Else<br>
Set mobjPersist = CreateObject(&quot;LocalDB.MyObjectPersist&quot;, MYMACHINE)<br>
End If<br>
<br>
Basically, if the connection to the server is alive then get the data from there; otherwise, get it from the local workstation.<br>
<br>
Of course, this would mean that you would have to have a version of the Data-Centric tier on the user's workstation, but that shouldn't be a problem.<br>
<br>
The beauty of this is that the UI and the UI-Centric tiers are uneffected by all of this.<br>
<br>
If this sound reasonable to you then let me know so that we could possibly explore the details together -- two heads are better then one, mine anyway :)<br>
<br>
As with your situation, we're not doing this yet but will start the design soon and would like to start on the right path.<br>
<br>
Thanks!<br>
Tarek<br>

 
Cal,<br>
<br>
We have not started the design of this process yet. I like your idea to use disconnected recordsets and I will have to think about that solution. Go ahead and post part of the code so that we can get a clearer picture.<br>
<br>
One question: which tiers do you use to write and read the disconnected recordsets?<br>
<br>
I haven't worked with disconnected recordsets before but I'll take a guess on how this works. In the following section I'm ignoring the saving and retrieval of the disconnected recordset and just taking a stab at how the general flow of disconnected recordsets work -- correct me where I'm wrong:<br>
<br>
Data-Centric tier (application server machine):<br>
<br>
- Create the recordset<br>
- Disconnect the recordset<br>
- Serialize the data into a string variable<br>
- Send the string variable to the caller<br>
<br>
UI-Centric tier or Proxy tier (user machine):<br>
<br>
- Create an empty recordset<br>
- Deserialize the string variable into the recordset<br>
- Convert the recordset data into the Business Object (class)<br>
<br>
Tarek<br>
<br>
<br>
<br>

 
Hi,<br>
<br>
In relation to the design model you outlined, its pretty much the design I would outline, however I would not serialise the string for passover between layers. I would propose the follwing:<br>
Data-Centric tier (application server machine):<br>
<br>
- Create the recordset<br>
- Disconnect the recordset<br>
- Send the recordset to the caller<br>
<br>
UI-Centric tier or Proxy tier (user machine):<br>
<br>
- Convert the recordset data into the Business Object (class)<br>
<br>
The recordset is disconnect, so the data would move between components in much the same manner as the string would. It would not have to call back to the component continuosly as the data is static.<br>
<br>
A small sample of code:<br>
<br>
<br>
'DAL<br>
<br>
Dim Cn As New ADODB.Connection<br>
Dim rs As New ADODB.Recordset<br>
<br>
' Open connection.<br>
Cn.Open &quot;pubs&quot;, &quot;sa&quot;<br>
<br>
' Open titles your table.<br>
rs.Open &quot;select * from titles&quot;, Cn, adOpenDynamic, adBatchOptimistic<br>
<br>
'Connection now broke<br>
set rs.ActiveConnection = nothing<br>
<br>
'pass your recordset back<br>
functionname = rs<br>
<br>
'''''UI<br>
CLIENT SIDE<br>
<br>
'call function is an ADODB.Recordset<br>
callfunction = DAL.getrecords()<br>
<br>
'save your recordset locally<br>
callfunction.Save &quot;c:\myrecfs.txt&quot;<br>
<br>
''''''''''''''''''''''''''<br>
<br>
<br>
later on <br>
<br>
''''<br>
youradodbrecordset.Open &quot;c:\myrecs.txt&quot;<br>
youradodbrecordset.MoveFirst<br>
.....<br>
'reconnect<br>
youradodbrecordset.ActiveConnection = newconn<br>
youradodbrecordset.UpdateBatch adAffectAll<br>
<br>
''''''<br>
<br>
<br>
I know this code is <b><i>ROUGH</b></i> but you get the idea.<br>
<br>
C<br>
<br>
<br>

 
Hello,<br>
<br>
Thanks Calahans for your input. This seems to be a very nice simple process -- seems very clean.<br>
<br>
Two questions:<br>
<br>
1. How's the speed?<br>
<br>
2. In the Business Objects tier, you mention that we would convert the returned recordset into business objects. If the entire application changes to use a different database (say from SQL Server to Oracle), would that impact the Business Objects tier? I guess my &quot;real&quot; question is this: do recordsets &quot;look&quot; different depending on the database being used (e.g. does an Access recordset work the same as a SQL Server recordset or an Oracle recordset)? I would imagine that they all would have pretty much the same methods, MoveFirst, MoveNext, .EOF etc. In the Business Objects tier, would I need to change my declaration of the recordset depending on the database being used?<br>
<br>
Thanks!
 
Hi VB400,<br>
<br>
Speed is very faast (unless you are over using it - the users won't know).<br>
<br>
No recordsets don't look different. If you think about it by the time your business object is beinginitialsed all you are loking at is a VB rs - with the same methods and properties. As long as you keep the same table structure you should not come accross this kind of problem.<br>
<br>
You could use ADO and just change the connection string based on a tick box where the user could signal if the are out of office (as an idea).<br>
<br>
I know johnk says that his offcie develop with access and scale to SQL Server on the back. He seems to have no trouble - maybe he could comment. John?<br>
<br>
HTH<br>
<br>
C
 
<br>
Is John using disconnected recordsets or is he passing serialized strings?<br>
<br>
Tarek
 
Tarek & Calahans,<br>
<br>
Remember, my real techie knowledge is obsolete. If any of this doesn't track let me know & I'll get some good techie help on it here.<br>
<br>
We do all our development with Access RDBMS. We deploy to either Access or SQL Server. We think we could equally deploy with zero changes using Oracle, Informix, Sybase, DB2/400 & maybe others. We use ADO and Parameterized Command Objects along with Provider software which is specific to a particular RDBMS. Our application programmers no longer write any SQL statements. They pass coded commands with parameters to our data access module which sets up the commad objects. <br>
<br>
We read disconnected recordsets (to avoid any locking), then pass the data in multi-dimensioned arrays as variant variables. Very fast. Very easy for our code to work with. We gave up bound data controls and had to master a good 3rd party grid control.<br>
<br>
We reread single rows at the time to update. Of course we lock during these operations. Code supplied by our generators keeps track of any changes in data that might occur between the original read and the reread.<br>
<br>
We give up some performance. No stored procedures, although we hope to add that in the future. At that time we expect to give up having a single data access module which can be set to any RDBMS by setting a variable in an .ini file (should be in the registry, I know).<br>
<br>
Hope this helps. I know it all can be terribly confusing.<br>
<br>
JohnK
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top