Hello,
for one of my tasks, I would really like to use a distributed transaction. I connect to remote sql server using MDAC, and need remote updates to be in same transaction as local. I think it should be possible to use Microsoft Distributed Transaction Controller and it's COM objects, but I'm not really sure as to where to start.
Has anyone tried something like this in their Dynamics projects?
Thanks!
0
Comments
Start from reading about Distributed Transaction Coordinator service.
Then make connection to the remote database, using ADO automation objects (search Mibuso how to do that), and try to do some inserts or updates.
Once you've got error messages you will have a plenty of topics to search and learn, and more specific questions to ask
Slawek.
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
In single NAV function I make a connection to remote server using ADO and do some updates. Afterwards, I do some updates on local tables. If these fail, remote updates don't get rolled back.
I've read a bit on DTC, however, all the examples involve use of "using" construct, which is not available in NAV. So I'm not really sure as where to start.
If you're making ADO connection, ADO components doesn't know anything about any transactions on your local NAV SQL server. You are just sending SQL statement to remote server 'manually' from your code in client, not from SQL server.
Try to split your remote SQL execution into three pieces:
1. BEGIN TRAN
2. Actual SQL query updating table,
3. COMMIT TRAN
All three should be send using the same connection.
COMMIT TRAN should be executed after your local transaction is finished. If your code fails, and you don't send COMMIT TRAN, and your ADO connection will be closed then transacion on remote server will be rolled back.
DTC service will not be of any use here as what you are doing is NOT distributed transaction
It would be distributed transaction if you executed code on your local SQL server, and do some updates to remove tables via local SQL, either using OPENROWSET query, via linked server.
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
How does SSIS manage to rollback such transactions if one of later local operations fail? It manages to do that even from non-MS servers! So it *is* possible
I'm not saying that it is not possible. What I am saying is that you are NOT doing distributed transactions.
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
Anyway, your suggestion about sending commit tran after local updates sounds very good. However, at the moment I'm using ADOCommand to execute remote stored procedure to do the updates. Is it possible to wrap it all in remote transaction somehow?
1. Made by NAV to SQL server
2. Made by you using ADO to remote server.
Each connection maintains its OWN transactions. While you can change properities of yor remote server connection, madre using ADO, and fully decide about its parameters, you cannot do anything with NAV connection. It is estabilished long before your code starts.
What you could try is to read NAV connection token (or whatever it is called - I don't remember now), and try to use the same token (or some of its parameters) when preparing your second connection. I've never done this before, but I've read something some time ago about transaction sharing between different connectiosn. This was regargind transaction sharing beteen two connections made to one MS SQL server, so it will no be a solution for you, but it might give you some other clues that you can do/read from exidting connection.
In my opinion you will not be able to fully mimic SSIS behaviour, as SSIS opens all connections made to different sources using DTC, and this is something what you will not be able to change in NAV client.
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
You gave me a great idea, about managing remote transactions myself. Unfortunately, it seems that even if error occurs, NAV doesnt clear automation objects, so remote connection stays hanging.. I've even tried it in if codeunit.run mode, it still won't work. Pity.
That is going to be a little tricky..
At first try if clearing ADO connection (using CLEAR(ACOvariable)) without submitting CommitTran rollbacks your transaction. It should. If it does then all your ADO variables should be delcared as local in the same proc which is used to make modifications in NAV. When NAV error occures local variables should get cleared, ADO connection closed an remote transactions rolled back.
If this doesn't work probably you need to make global single instance codeunit maintaining all your ADO interface variables and code. Then you should rollbalck any transaction before you start new, and make sure your code commits ADO transaction at the end. Not very sophisticated, and it could leave open remote transaction for LOOOONG time (which may lead to serious troubles), but should work.
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
Then I thought about single instance codeunit. Am going to try it now, but I don't really like this approach..
I see - you tried your code faster than I wrote my response
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
unfortunately, seems it doesn
and check if CLEAR(ADOConn) rollback transaction ? Perhaps you need to add SET XACT_ABORT ON ; in your SQL code (or its equivalent in ADO connection parameters) ?
EDIT
Why you're doing this:
TmpVariant := AdoConn;
AdoCommand.ActiveConnection(TmpVariant);
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
I'm not sure about XACT, will have to read about it.
I'm doing that via variant, because otherwise NAV whines about incompatible data types:(