-
try to create local class in the UI code, then put the class code from the COM object in it, then try to run it (be sure to remove reference to the COM object before).
if it already have a problem, then the problem stem from the code, if not, it is maybe COM+ problem.
-
hai deja,
yes it is a problem with my code. the problem is i am executing the statement gctx.setcomplete at the end of the function. so the public variable doesn't contain anything. if i remove that statement it is working fine.
now i am facing another problem with transactions. first of all i need to insert one record in master table. after that i need to insert some records in child table. so till now i am using begintrans before saving and committrans after completing.
but now if i use connection per method invocation, if i open and close the connection in the method itself, how can i begin and commit the transactions?
till now i am following like this.
connection.begintrans
call masters save method
call child records save method
connection.committrans
if there is any error between, connection.rollbacktrans.
so if i open one connection is masters save method, and close it, if there is any error in childs save method, the master record is saved in the database.
so how to resolve this problem? pls help me
-
u don't have to use BeginTrans etc. at all.
what u have to do is:
create specific class to save or update etc. then set the property MTSTransactionMode to RequiresTransaction (or through the COM+ MMC, right click on that class, choose properties, and in the Transactions tab choose Required).
this class will create the business class (that contain masters save method etc.) and after that will call SetComplete (or SetAbort in failure case, in the error handling).
now, make sure to mark the business class (with the masters save method, child records save method etc.) as Transaction Supported (same way as the above example), and also the data services class (if u create one).
it is very simple, because COM+ take care to handle the transaction, even if it seems to u that u r actually closing the connection after each method, COM+ hold the connection open behind the scenes, and if u have error in the latter method (even if the first one have succeeded) the code goes to the error handle and over there it calls SetAbort which abort the whole transaction.
for example
Class TransactionHandle:
Public Sub UpdateData()
On Error GoTo ErrorHandle
Dim obj As DLL.Class_BUS
Set obj = New DLL.Class_BUS
obj.SaveMaster
obj.SaveChilds
' do what ever u like
Set obj = Nothing
GetObjectContext.SetComplete
Exit Sub
ErrorHandle:
Set obj = Nothing
GetObjectContext.SetAbort
' take care of error
End Sub
this class mark as Transaction Required.
and the client will use:
Dim obj As DLL.TransactionHandle
Set obj = New DLL.TransactionHandle
obj.UpdateData
Set obj = Nothing
that's it
try it.
-
hai deja,
yes it is working fine if there is one class for data access. but in my modules there are 5 classes for data access. each class is related to particular module. so sometimes i need to execute methods in different classes. at that time how can i manage the transactions?
is there any way?
-
yes u can.
as i told u, every class can participate in a transaction as long is it mark as Transaction Supported.
those classes, only supported in transaction, ie. they can also being create in other context (JIT, Synchronization etc).
but if u mark class as Transaction Required or Transaction Required New, then COM+ will create transaction (existing or new).
-
but i think my case is little bit different,
UI part
dim cls as someclass
set cls = new someclass
dim cls1 as someclass1
set cls1 = new someclass1
cls.updatedata
if <somecondition> then
cls1.updatecontrol()
end if
someclass
public sub updatedata()
dim clsmas as clsmaster
dim clsch as clschild
clsmas.saverecords()
clsch.saverecords()
if not ctx is nothing then ctx.setcomplete()
end sub
someclass1
public sub updatecontrol()
' some database updates
end sub
in the above case, "someclass" has the value "transaction required" and clsmaster and clschild has the properties "supported transactions".
so in my ui after cls.updatedata is it comming the transaction, but i want to commit the transaction after cls1.updatecontrol.
how is it?
-
why can't u call someclass1 from someclass?
is that a problem?
if u want to that someclass1 will participate in the transaction, u must include it in the transaction context of someclass (mark it as Transaction Supported)
u can do such thing:
UI part
dim cls as someclass
set cls = new someclass
if <somecondition> then
cls.updatedata
end if
someclass
public sub updatedata()
dim clsmas as clsmaster
dim clsch as clschild
dim cls1 as someclass1
set cls1 = new someclass1
clsmas.saverecords()
clsch.saverecords()
cls1.updatecontrol()
if not ctx is nothing then ctx.setcomplete()
end sub
-
hai deja,
in my present situation, it is not possible to call someclass1 from someclass. these two are entirely different. im using that someclass1 for critical updates and that will be used very rarely depending on the users input.
so i want to commit the transaction after the update in someclass1. is it possible is any other way? if possible pls tell me.
-
so, how about new class that will corporate this two classes?
UI part
Dim obj As new_class
Set obj = New new_class
obj.ExecTransaction
Set obj = Nothing
new_class
Public Sub ExecTransaction()
dim cls as someclass
set cls = new someclass
dim cls1 as someclass1
set cls1 = new someclass1
cls.updatedata
if <somecondition> then
cls1.updatecontrol()
end if
End Sub
-
hai deja,
yes, it is quite useful from me. i will try to change like that.
now i got another problem. if i make my application to support appartment threading, my global variables doesn't hold any values. if i make it single threaded, all the global varibales are fine with their values.
why?
-
ho!
u finally enter the real thing.
i hope u have good understanding about COM apartment, cause if u not, u MUST read the following articles:
http://codeguru.earthweb.com/activex...artments1.html
http://codeguru.earthweb.com/activex...artments2.html
VB support only one kind of COM apartment - the STA.
STA or Single Thread Apartment said to be thread affinity, that means that the object is very close to the thread who create it and only that thread have straight access to the object. if another thread want to access that object either, it can, but only through proxy.
the reason for that is concurrency problems.
when two or more clients want to access an object simultaneously, one can harm each other data due to the threading model of the windows os. the system switch between threads in a manner that the object can't control (i.e. arbitrary), now, if one object have to read some data (var x) from the object to calculate something and just before that time, the os had a switch to other thread (i.e. other client), and that client had decided to modify that piece of data (var x), then the first client will get uncertain data, the rest of the program goes to nowhere.
there r several ways to challenge those problems (mutex, critical section etc), but this func belong to c/c++ programmers.
if u write COM objects with tools like c/c++ u can design MTA objects.
MTA or Multiple thread apartment objects can handle the concurrency problems itself, without help from COM (as the case in STA).
generally, each COM+ application had it's own process (DLLHOST.EXE). COM+ will create threads as long as it need to handle clients requests for objects.
now, if u have STA object (as u write with VB), COM+ will create new thread (STA) for each client.
the difference between Single Thread and Apartment Thread in the Project Properties is that if u choose Single Thread COM will create that object only one per process (in the main STA). the latter case will cause to create new STA for each object.
so, if u choose Single Thread, u actually have only one instance of that object, what taking us to the first discussion of COM singleton, and u loosing the load balancing effect of the COM+.
but, if u still want to support each client with it's own instance of the object, and still share some data between them u cand use SPM.
SPM (Shared Property Manager) is a COM+ mechanism to share data between clients (or threads) in the same process.
read more about the SPM in MSDN.
u have other options to share data between threads, don box explain it very good:
http://www.microsoft.com/msj/default...598/newnav.htm
-
hai deja,
with the help of you, i implemented just in time, transactions successfully. really the above documents gave me a good idea on threading model.
till now im using STA. there is no problem. if i want to use apartment threading, do i need to write any extra code?
if i use STA, all the calls to the object will be queued. how to manage these queued messages? any problems in that?
really thanx a lot for your help