|
-
Sep 30th, 2008, 06:22 AM
#1
Thread Starter
Lively Member
ADO Transactions with SQLSERVER(??)
Hi All,
I designed an client/server application which updates and reads data from and to server.
I am having a big problem in transactions, The Code is :
Provider Used to open connection with SQL Server 2005 : sqloledb
Code:
Private Function UpdateRemoteDB()
On Error GoTo ErrHnd
Dim Con as New ADODB.Connection
Dim rsSQL as New ADODB.Recordset
Con.CursorLocation = adUseServer
Con.ConnectionString = SQLCONNECTIONSTRING
Con.Open
'Later update each record from local database to server
Do While not rsLocalRecord.EOF = True
Con.BeginTrans
rsSQL.CursorLocation = adUseClient
rsSQL.Open "SELECT * FROM MyTable WHERE ID = '11'", _
Con, adOpenKeyset, adLockOptimistic
rsSQL("Field1") = rsLocalRecord("Field1")
rsSQL("Field2") = rsLocalRecord("Field2")
rsSQL("Field3") = rsLocalRecord("Field3")
:
:
rsSQL.Update
rsSQL.Close
'I need to do some other processing here.
If OtherFunction() = False then
GoTo ErrHnd
End If
Con.CommitTrans
Loop
Exit Function
ErrHnd:
Con.RollbackTrans
End Function
On other Client End I just displayed all the updated records from SQL Server
with "SELECT * FROM MyTable" and show them to grid.
The main problem above is while my first client is in transaction till the CommitTrans is not executed my other client cannot displayed the results for query.
What should I can do so that the Concurrent Updates are possible!!!!!!
I read about Connection Properties in MSDN so tried likewise
Con.Mode = adModeShareDenyNone
Con.IsolationLevel = adXactReadCommitted
But nothing really happens !!!!
Thanks !!!!!!!!
Last edited by si_the_geek; Sep 30th, 2008 at 06:26 AM.
Reason: added code tags
-
Sep 30th, 2008, 06:39 AM
#2
Re: ADO Transactions with SQLSERVER(??)
That behaviour is basically expected, and despite the annoyance is a good thing - the records are being changed, so showing them in a mid-way state would be misleading.
What you should do is keep transactions as brief as possible, so that the delay is small enough to ignore.
In the code you posted there are two obvious ways to speed it up, the first is to not use a recordset for updating records - instead use a Insert statement, preferably via a Command object. For examples, see the article How can I add a record to a database? from our Database Development FAQs/Tutorials (at the top of this forum). For the way to use a Command object with a loop, see here.
The other issue is the way you declare the object variables, which slows down all of the usage of them - I would recommend reading the article Why shouldn't I use "Dim .. As New .."? from our Classic VB FAQs (in the FAQ forum, which is shown near the top of our home page)
I have no idea what the Do/Loop is about (as you don't do a .MoveNext etc), or what is in OtherFunction, but there is a good chance that they could be improved too.
-
Sep 30th, 2008, 06:40 AM
#3
Re: ADO Transactions with SQLSERVER(??)
Are you really just updating a single record in each iteration of that loop?
If that is the case then there is a much better way to accomplish this without holding transactions open in the client!
-
Oct 1st, 2008, 01:57 AM
#4
Re: ADO Transactions with SQLSERVER(??)
Basing on your sql I think it can be done with one action query or that you may try to modify it like this..
Code:
Con.BeginTrans
Do While not rsLocalRecord.EOF = True
rsSQL.CursorLocation = adUseClient
rsSQL.Open "SELECT * FROM MyTable WHERE ID = '11'", _
Con, adOpenKeyset, adLockOptimistic
rsSQL("Field1") = rsLocalRecord("Field1")
rsSQL("Field2") = rsLocalRecord("Field2")
rsSQL("Field3") = rsLocalRecord("Field3")
:
:
rsSQL.Update
rsSQL.Close
'I need to do some other processing here.
If OtherFunction() = False then
GoTo ErrHnd
End If
Loop
Con.CommitTrans
-
Oct 1st, 2008, 04:15 AM
#5
Re: ADO Transactions with SQLSERVER(??)
I was going to suggest an action query - but need to wait for clarification on what the whole loop is doing.
Locking is a bad idea from the client - always - as is being experienced by the OP now.
-
Oct 4th, 2008, 01:32 AM
#6
Thread Starter
Lively Member
-
Oct 4th, 2008, 01:51 AM
#7
Re: ADO Transactions with SQLSERVER(??)
On your 2nd question Access (being file based) can not have 2 process updating the same record at the same time.
-
Oct 4th, 2008, 02:00 AM
#8
Thread Starter
Lively Member
Re: ADO Transactions with SQLSERVER(??)
Hi brin,,
I am not updating same record at the same time but updating same table at the same time, in which two different records are updating.
-
Oct 4th, 2008, 07:18 AM
#9
Re: ADO Transactions with SQLSERVER(??)
Stop using transactions.
Stop getting a recordset to perform a simple update.
Start using ACTION QUERIES.
Code:
strSql = "Update MyTable Set Field1='" & rsLocalRecord("Field1") _
& ", Field2='" & rsLocalRecord("Field2") _
.
.
.
& " Where Id='11'"
Build that string and then use .Execute on your connection object to run it.
This requires no lock - no transaction - no hold on the DB.
That's a more proper way to update records in my opinion.
-
Oct 5th, 2008, 05:07 AM
#10
Thread Starter
Lively Member
Re: ADO Transactions with SQLSERVER(??)
Hi szlamany,
You are correct to use action querys in simple updates.
But its my need to rollback the transactions too.
Also if I use simple updates the record which is updated and for which the local process is still running, have been seen by the client and thus lead to misbehaviour.
Regds,
-
Oct 5th, 2008, 08:44 AM
#11
Re: ADO Transactions with SQLSERVER(??)
Then there is an answer to that issue as well.
Most people don't want to think set-based - it's so much easier to program in an iterative fashion.
But to truly utilize SQL you must always be set-based.
The simple set-based solution to your problem is to load a temp table with the new data first. MS SQL offer bulk insert options - both at command line and also part of the SQL Client - to get that data loaded in one shot.
Once you get the data into a temp table you can do a single UPDATE statement to process all rows.
We do this in literally hundreds of places - loading all kinds of data in these ways.
Expecting to use transactions to manage errors and then do rollbacks is not appropriate.
You should be creating temp tables.
Then you could delete the rows that aren't good to load.
Then you could do the UPDATE all in one step - syntax would be something like this.
Code:
Update MyTable Set Column1=TT.Column1, Column2=TT.Column2
From #TempTable TT
Left Join MyTable MT on MT...=TT...
Where {some great condition statement to make sure the UPDATE will not fail}
Taking data into VB to be processed one row at a time in a multi-user environment is a poor choice when you have other set-based "single" shot ACTION QUERY abilities that fully respect set-based logic.
If you want assistance with doing this in a set-based fashion step back and tell us what you are trying to actually achieve. What the source of the data is - a couple of columns of sample data - and you will be amazed at how easy this can be done without looping through rows in VB and causing deadlock issues with your database
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|