 |
|
 |
|
|
 |
Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
02-23-05 10:58 PM
Can anyone help?
I am trying to create a transactional receive adapter. I
have a ServicedComponent class which is responsible for
retrieving the data from SQL Server, then constructing
and submitting the BizTalk messages. It runs in a new
DTC transaction. Everything seems to work, but there is
one discrepancy:
Reading the documentation when you call the Done() method
you should be given a handle to a IBTDTCCommitConfirm
instance. When I debug this I find that it is a null
reference (undefined value). In the BatchComplete()
method of the IBTBatchCallback interface (implemented in
the same class), I check the status and either call
SetComplete() or SetAbort() accordingly. What I can't
figure out is what should I do with the
IBTDTCCommitConfirm instance as it is null? And does
this indicate that I am doing something wrong wrt to the
transaction. All the documentation I can find talks
about using transactions, but I haven't actually seen any
code that demonstrates it.
Any help gratefully received.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
02-23-05 10:58 PM
Hi Tim,
> I am trying to create a transactional receive adapter. I
> have a ServicedComponent class which is responsible for
> retrieving the data from SQL Server, then constructing
> and submitting the BizTalk messages. It runs in a new
> DTC transaction. Everything seems to work, but there is
> one discrepancy:
>
> Reading the documentation when you call the Done() method
> you should be given a handle to a IBTDTCCommitConfirm
> instance. When I debug this I find that it is a null
> reference (undefined value). In the BatchComplete()
> method of the IBTBatchCallback interface (implemented in
> the same class), I check the status and either call
> SetComplete() or SetAbort() accordingly. What I can't
> figure out is what should I do with the
> IBTDTCCommitConfirm instance as it is null? And does
> this indicate that I am doing something wrong wrt to the
> transaction. All the documentation I can find talks
> about using transactions, but I haven't actually seen any
> code that demonstrates it.
You would only get an IBTDTCCommitConfirm instance back from Done() if you
passed in an ITransaction instance as the argument. You should then keep it
around and call it when the actual DTC transaction commits (not when BTS
says the batch is complete). If you are indeed passing an ITransaction
instance to Done() and you're still getting a null pointer out of it, then
something is really wrong here...
--
Tomas Restrepo
tomasr@mvps.org
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
02-25-05 12:48 PM
Thanks for the reply.
This ITransaction was the thing that I was unsure about
from the documentation. When I call the batch.Done()
method I pass the ContextUtil.Transaction. Is this the
right transaction, i.e. a DTC Transaction?
>-----Original Message-----
>Hi Tim,
>
adapter. I[vbcol=seagreen]
is[vbcol=seagreen]
method[vbcol=seagreen]
in[vbcol=seagreen]
the[vbcol=seagreen]
any[vbcol=seagreen]
>
>You would only get an IBTDTCCommitConfirm instance back
from Done() if you
>passed in an ITransaction instance as the argument. You
should then keep it
>around and call it when the actual DTC transaction
commits (not when BTS
>says the batch is complete). If you are indeed passing
an ITransaction
>instance to Done() and you're still getting a null
pointer out of it, then
>something is really wrong here...
>
>
>--
>Tomas Restrepo
>tomasr@mvps.org
>
>
>.
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
02-25-05 12:48 PM
Hi,
> Thanks for the reply.
>
> This ITransaction was the thing that I was unsure about
> from the documentation. When I call the batch.Done()
> method I pass the ContextUtil.Transaction. Is this the
> right transaction, i.e. a DTC Transaction?
Yes, it is a DTC Transaction. If it still doesn't work, try casting
ContextUtil.Transaction to ITransaction before passsing it to Done().
BTW, I wrote this a few days ago on the topic...
http://www.winterdom.com/weblog/archives/000458.html
--
Tomas Restrepo
tomasr@mvps.org
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
03-01-05 12:47 PM
I feel like I am almost there, but I have one remaining issue.
I have built my adapter with a pre-compiler option so that I can either use
transactions or not. When I run them as non-transactional
(non-ServicedComponent), all works fine.
When I switch to transactional ServicedComponents I get an error when my
adapter tries to submit a message into BizTalk, the status =
E_BTS_PERSISTENCE_FAILURE = -1061153182
Since this works when I don't use a tx it can't be message format issue. I
can't find any information about this particular error message.
As ever any hints, tips or just blind guesses would be appreciated!
Tim
"Tomas Restrepo (MVP)" wrote:
> Hi,
>
>
> Yes, it is a DTC Transaction. If it still doesn't work, try casting
> ContextUtil.Transaction to ITransaction before passsing it to Done().
>
> BTW, I wrote this a few days ago on the topic...
> http://www.winterdom.com/weblog/archives/000458.html
>
> --
> Tomas Restrepo
> tomasr@mvps.org
>
>
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
03-03-05 01:47 AM
Hi Tim,
> I feel like I am almost there, but I have one remaining issue.
>
> I have built my adapter with a pre-compiler option so that I can either
use
> transactions or not. When I run them as non-transactional
> (non-ServicedComponent), all works fine.
>
> When I switch to transactional ServicedComponents I get an error when my
> adapter tries to submit a message into BizTalk, the status =
>
> E_BTS_PERSISTENCE_FAILURE = -1061153182
>
> Since this works when I don't use a tx it can't be message format issue.
I
> can't find any information about this particular error message.
>
> As ever any hints, tips or just blind guesses would be appreciated!
Which method call gives you that particular error? Maybe that can help us
narrow it down!
--
Tomas Restrepo
tomasr@mvps.org
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
03-04-05 12:47 PM
This is the status I get back when the BatchComplete callback is executed.
This occurs when I am submitting messages into BizTalk.
I have a BatchSubmitter Class (derived from ServicedComponent), which
RequiresNew transaction. In the method called SubmitMessages it does the
following (pseudocode):
batch = tp.GetBatch();
factory = tp.GetMessageFactory();
foreach(myMessage in myMessages)
{
bizTalkMessage = factory.CreateMessage();
// Create context and set properties, including InboundTransportLocation
and InboundTransportType
body = factory.CreateMessagePart();
// set body to a MemoryStream and write message
message.AddPart("body", body, true);
// Delete message from my custom database
batch.SubmitMessage(message);
}
(IBTDTCCommitConfirm) confirmation batch.Done(ContextUtil.Transaction);
In the BatchComplete() method I have the following code:
if (status == 0){
ContextUtil.SetComplete();
confirmation.DTCCommitConfirm(ContextUtil.Transaction, true);
}
else{
ContextUtil.SetAbort();
confirmation.DTCCommitConfirm(ContextUtil.Transaction, false);
}
One thing I'm not sure about is whether I need to set the MessageID on the
message I am submitting into BizTalk. As stated earlied this code works
without COM+.
Thanks
"Tomas Restrepo (MVP)" wrote:
> Hi Tim,
> use
> I
>
> Which method call gives you that particular error? Maybe that can help us
> narrow it down!
> --
> Tomas Restrepo
> tomasr@mvps.org
>
>
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
03-05-05 07:46 AM
Hi Tim,
> This is the status I get back when the BatchComplete callback is executed.
> This occurs when I am submitting messages into BizTalk.
>
> I have a BatchSubmitter Class (derived from ServicedComponent), which
> RequiresNew transaction. In the method called SubmitMessages it does the
> following (pseudocode):
>
> batch = tp.GetBatch();
>
> factory = tp.GetMessageFactory();
>
> foreach(myMessage in myMessages)
> {
> bizTalkMessage = factory.CreateMessage();
>
> // Create context and set properties, including InboundTransportLocation
> and InboundTransportType
>
> body = factory.CreateMessagePart();
>
> // set body to a MemoryStream and write message
>
> message.AddPart("body", body, true);
>
> // Delete message from my custom database
>
> batch.SubmitMessage(message);
> }
>
> (IBTDTCCommitConfirm) confirmation batch.Done(ContextUtil.Transaction);
>
>
> In the BatchComplete() method I have the following code:
>
> if (status == 0){
> ContextUtil.SetComplete();
> confirmation.DTCCommitConfirm(ContextUtil.Transaction, true);
> }
> else{
> ContextUtil.SetAbort();
> confirmation.DTCCommitConfirm(ContextUtil.Transaction, false);
> }
>
> One thing I'm not sure about is whether I need to set the MessageID on the
> message I am submitting into BizTalk. As stated earlied this code works
> without COM+.
Ahh, now I get it, at least partially. One problem I see is that the
BatchComplete event is fired of in another thread, that is outside the
context of your original COM+ transaction. That, by itself, will screw you
up.
Even if it didn't, you'd still be in problems because you're not supposed to
call IBTDTCCommitConfirm.CommitConfirm() when you vote on your COM+
transaction (through SetComplete() and SetAbort()), but rather only *after*
the transaction has actually been commited or aborted. In your case, the
SetComplete() and SetAbort() calls don't actually force completion of the
transaction, they merely vote on the transaction, which is only commited or
aborted after the COM+ root object is deactivated. This makes it very tricky
to implement a transactional receive adapter as a ServicedComponent; hence
the object of the previous article I refered you to before.
Also, no, you don't need to specifically set the message id, however, it is
common to at least set the InboundTransportType and InboundTransportLocation
properties on the context before submitting.
Finally, one thing: You call batch.Done(ContextUtil.Transaction); I believe,
but I don't remember for sure, that it doesn't work, and that you need to
cast ContextUtil.Transaction to an ITransaction instance explicitly for it
to be marshaled correctly ...
--
Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/weblog/
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Calling IBTTransportBatch.Done with transaction |
 |
 |
|
|
03-07-05 12:46 PM
Thanks Tomas for your help. I will make sure I read your article. I had
automatically assumed that a ServicedComponent was the way to go when using
a
DTC transaction. Time to read up on COM+ CRMs!
Tim
"Tomas Restrepo (MVP)" wrote:
> Hi Tim,
>
>
> Ahh, now I get it, at least partially. One problem I see is that the
> BatchComplete event is fired of in another thread, that is outside the
> context of your original COM+ transaction. That, by itself, will screw you
> up.
>
> Even if it didn't, you'd still be in problems because you're not supposed
to
> call IBTDTCCommitConfirm.CommitConfirm() when you vote on your COM+
> transaction (through SetComplete() and SetAbort()), but rather only *after
*
> the transaction has actually been commited or aborted. In your case, the
> SetComplete() and SetAbort() calls don't actually force completion of the
> transaction, they merely vote on the transaction, which is only commited o
r
> aborted after the COM+ root object is deactivated. This makes it very tric
ky
> to implement a transactional receive adapter as a ServicedComponent; hence
> the object of the previous article I refered you to before.
>
> Also, no, you don't need to specifically set the message id, however, it i
s
> common to at least set the InboundTransportType and InboundTransportLocati
on
> properties on the context before submitting.
>
> Finally, one thing: You call batch.Done(ContextUtil.Transaction); I believ
e,
> but I don't remember for sure, that it doesn't work, and that you need to
> cast ContextUtil.Transaction to an ITransaction instance explicitly for it
> to be marshaled correctly ...
>
> --
> Tomas Restrepo
> tomasr@mvps.org
> http://www.winterdom.com/weblog/
>
>
>
>
>
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 10:36 AM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|