Working Transactions somehow started not to work

  • Thread starter Thread starter Ömer Ayzan
  • Start date Start date
Ö

Ömer Ayzan

Dear friends,

I encountered such a problem and do not know how to correct it:

I am using XP Professional, Office 2003 (SP2) and SQL2000

I'd like to use a transaction on one to many form. Specifically I have
Bank(main form) and Branches (Subform)
These are designed as bound forms to TB_BANK & TB_BRANCH tables
respectively. However in order to use a transaction I open another
connection and with this connection
I start a transaction (Code as follows) at the open event of the main form.
When user chooses to save whatever he has done with the form I commit
otherwise rollback.

Up until this morning this approach was working perfectly. While debugging
on the run Access hanged couple of times. Even though
I recovered thru 'Compact & Repair Project' my ability to rollback has gone.
Assuming that sth has happened to db I run SQL Querry analyzer and tried
updating tables under transaction and no problem. I have other adp's using
the very same approach they also work fine.

To eliminate the problem I created a new adp and copied only the above forms
& code behind it and still the same thing. For any one who could propose sth
the code is as follows:

Private mlngOpMode As openMode
Private mcnnMain As New ADODB.Connection
Private mrstBank As New ADODB.Recordset
Private mrstBranch As New ADODB.Recordset

Private Sub Form_Open(Cancel As Integer)
Dim strSqlMain As String
Dim strSQLSub As String
Dim strFilter As String
Dim lngCallerForm As Long
Dim strWhere As String

Dim varOparg As Variant
Dim strNewData As String


' Format of strOpenArg:
' openMode;NewData;CallerField;CallerForm;Filter

Me.ServerFilter = ""

varOparg = Split(Me.OpenArgs, ";")
Me.Caption = CStr(varOparg(0)) ' Caption
mlngOpMode = CLng(varOparg(1)) ' Open Mode
strNewData = CStr(varOparg(2)) ' New Data
' Caller Field
' Caller Form
strFilter = CStr(varOparg(5)) ' Filter

With mcnnMain
.ConnectionString = CurrentProject.Connection
.Open
.BeginTrans
End With

' MainForm Recordsource
strSqlMain = "SELECT * FROM AYZ_TB_BANK WHERE " & strFilter
' SubForm Recordsource
strSQLSub = "SELECT * FROM AYZ_TB_BRANCH WHERE " & strFilter

mrstBank.Open strSqlMain, mcnnMain, adOpenKeyset, adLockOptimistic
mrstBranch.Open strSQLSub, mcnnMain, adOpenKeyset, adLockOptimistic

Set Me.Recordset = mrstBank
Set Form_AYZ_SUBFRM_BRANCH.Recordset = mrstBranch

Private Sub cmdCancel_Click()
Dim strMsg As String, userResponse As VbMsgBoxResult
Dim strWhere As String
Dim strSQL As String

On Error GoTo Err_cmdCancel_Click

If Me.cmdSave.Enabled Then
strMsg = "Yaptýðýnýz deðiþiklikler iptal edilecektir."
userResponse = DisplayMessage(strMsg, vbExclamation + vbOKCancel)

If userResponse = vbOK Then
mcnnMain.RollbackTrans
Else
GoTo Exit_cmdCancel_Click
End If
End If
DoCmd.Close acForm, Me.Name

Exit_cmdCancel_Click:
Exit Sub
Err_cmdCancel_Click:
DisplayMessage Err.Number & ": " & Err.Description, vbCritical +
vbOKOnly, "HATA!"
Resume Exit_cmdCancel_Click

End Sub


Private Sub cmdSave_Click()
Dim strMsg As String, lngBankID As Long, strWhere As String
On Error GoTo Err_cmdSave_Click

If IsNull(Me.txtBankCode) Then
strMsg = "'Banka Kodu' boþ olamaz."
DisplayMessage strMsg, vbOKOnly + vbCritical, "UYARI!"
Me.txtBankCode.SetFocus
GoTo Exit_cmdSave_Click
End If

mcnnMain.CommitTrans

DoCmd.Close acForm, Me.Name
Exit_cmdSave_Click:

Exit Sub
Err_cmdSave_Click:
MsgBox Err.Description
Resume Exit_cmdSave_Click
End Sub

Private Sub Form_Close()
Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID
' A little bit of house keeping
Set mrstBank = Nothing
Set mrstBranch = Nothing
Set mcnnMain = Nothing
End Sub

Private Sub Form_Dirty(Cancel As Integer)
cmdSave.Enabled = True
End Sub
 
you should give more information

also; this makes me a little bit nervous
Private Sub Form_Close()
Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID

is this in the form_ayx_frm_bankbr_close event or in the other form?

and I would probably ass this
.ConnectionString = CurrentProject.Connection
to

.ConnectionString = CurrentProject.Connection.ConnectionString
just to make sure it's not doing anything funny
 
Hello Ömer,

you probably will be surprised, or maybe even won't believe, but the code
you posted could not work ever; at least, reliably. Unlike MDB, with ADP,
begintrans, committrans, and rollback are practically ignored. See for
example http://support.microsoft.com/kb/223213 - it's easy to see that the
results would be unpredictable.

Also see
http://www.eggheadcafe.com/aspnet_answers/AccessadpSQLServer/Jan2006/post25750796.asp
- Sylvain's comment. There's workaround, but it's unsupported and also may
bring unpredictable results - see my comment in the end of the above page.

From all my experience of working with ADP, the best results are achieved by
allowing Access to manipulate the data its own way, rather than trying to
force it to do what you want. For example, it's better to specify
recordsource for a form rather than set me.recordset=<pre-created
recordset> - i.e. allow Access to build the recordset as it wants, rather
than force it to use yours. The path of forcing your way on Access is paved
with numerous hours of troubleshooting unpredictable behaviours exactly like
what you just encountered.

The best tool for working with transactions and proper locking is VB6.
Everything else (Access, and VS.Net) is using client-based cursors.

Vadim Rapp


You wrote in conference microsoft.public.access.adp.sqlserver on Fri, 6 Oct
2006 13:57:18 +0300:

ÖA> Dear friends,

ÖA> I encountered such a problem and do not know how to correct it:

ÖA> I am using XP Professional, Office 2003 (SP2) and SQL2000

ÖA> I'd like to use a transaction on one to many form. Specifically I have
ÖA> Bank(main form) and Branches (Subform)
ÖA> These are designed as bound forms to TB_BANK & TB_BRANCH tables
ÖA> respectively. However in order to use a transaction I open another
ÖA> connection and with this connection
ÖA> I start a transaction (Code as follows) at the open event of the main
ÖA> form. When user chooses to save whatever he has done with the form I
ÖA> commit otherwise rollback.

ÖA> Up until this morning this approach was working perfectly. While
ÖA> debugging on the run Access hanged couple of times. Even though
ÖA> I recovered thru 'Compact & Repair Project' my ability to rollback has
ÖA> gone. Assuming that sth has happened to db I run SQL Querry analyzer
ÖA> and tried updating tables under transaction and no problem. I have
ÖA> other adp's using the very same approach they also work fine.

ÖA> To eliminate the problem I created a new adp and copied only the above
ÖA> forms & code behind it and still the same thing. For any one who could
ÖA> propose sth the code is as follows:

ÖA> Private mlngOpMode As openMode
ÖA> Private mcnnMain As New ADODB.Connection
ÖA> Private mrstBank As New ADODB.Recordset
ÖA> Private mrstBranch As New ADODB.Recordset

ÖA> Private Sub Form_Open(Cancel As Integer)
ÖA> Dim strSqlMain As String
ÖA> Dim strSQLSub As String
ÖA> Dim strFilter As String
ÖA> Dim lngCallerForm As Long
ÖA> Dim strWhere As String

ÖA> Dim varOparg As Variant
ÖA> Dim strNewData As String

ÖA> ' Format of strOpenArg:
ÖA> ' openMode;NewData;CallerField;CallerForm;Filter

ÖA> Me.ServerFilter = ""

ÖA> varOparg = Split(Me.OpenArgs, ";")
ÖA> Me.Caption = CStr(varOparg(0)) ' Caption
ÖA> mlngOpMode = CLng(varOparg(1)) ' Open Mode
ÖA> strNewData = CStr(varOparg(2)) ' New Data
ÖA> ' Caller Field
ÖA> ' Caller Form
ÖA> strFilter = CStr(varOparg(5)) ' Filter

ÖA> With mcnnMain
ÖA> .ConnectionString = CurrentProject.Connection
ÖA> .Open
ÖA> .BeginTrans
ÖA> End With

ÖA> ' MainForm Recordsource
ÖA> strSqlMain = "SELECT * FROM AYZ_TB_BANK WHERE " & strFilter
ÖA> ' SubForm Recordsource
ÖA> strSQLSub = "SELECT * FROM AYZ_TB_BRANCH WHERE " & strFilter

ÖA> mrstBank.Open strSqlMain, mcnnMain, adOpenKeyset, adLockOptimistic
ÖA> mrstBranch.Open strSQLSub, mcnnMain, adOpenKeyset, adLockOptimistic

ÖA> Set Me.Recordset = mrstBank
ÖA> Set Form_AYZ_SUBFRM_BRANCH.Recordset = mrstBranch

ÖA> Private Sub cmdCancel_Click()
ÖA> Dim strMsg As String, userResponse As VbMsgBoxResult
ÖA> Dim strWhere As String
ÖA> Dim strSQL As String

ÖA> On Error GoTo Err_cmdCancel_Click

ÖA> If Me.cmdSave.Enabled Then
ÖA> strMsg = "Yaptýðýnýz deðiþiklikler iptal edilecektir."
ÖA> userResponse = DisplayMessage(strMsg, vbExclamation +
ÖA> vbOKCancel)

ÖA> If userResponse = vbOK Then
ÖA> mcnnMain.RollbackTrans
ÖA> Else
ÖA> GoTo Exit_cmdCancel_Click
ÖA> End If
ÖA> End If
ÖA> DoCmd.Close acForm, Me.Name

ÖA> Exit_cmdCancel_Click:
ÖA> Exit Sub
ÖA> Err_cmdCancel_Click:
ÖA> DisplayMessage Err.Number & ": " & Err.Description, vbCritical +
ÖA> vbOKOnly, "HATA!"
ÖA> Resume Exit_cmdCancel_Click

ÖA> End Sub

ÖA> Private Sub cmdSave_Click()
ÖA> Dim strMsg As String, lngBankID As Long, strWhere As String
ÖA> On Error GoTo Err_cmdSave_Click

ÖA> If IsNull(Me.txtBankCode) Then
ÖA> strMsg = "'Banka Kodu' boþ olamaz."
ÖA> DisplayMessage strMsg, vbOKOnly + vbCritical, "UYARI!"
ÖA> Me.txtBankCode.SetFocus
ÖA> GoTo Exit_cmdSave_Click
ÖA> End If

ÖA> mcnnMain.CommitTrans

ÖA> DoCmd.Close acForm, Me.Name
ÖA> Exit_cmdSave_Click:

ÖA> Exit Sub
ÖA> Err_cmdSave_Click:
ÖA> MsgBox Err.Description
ÖA> Resume Exit_cmdSave_Click
ÖA> End Sub

ÖA> Private Sub Form_Close()
ÖA> Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID
ÖA> ' A little bit of house keeping
ÖA> Set mrstBank = Nothing
ÖA> Set mrstBranch = Nothing
ÖA> Set mcnnMain = Nothing
ÖA> End Sub

ÖA> Private Sub Form_Dirty(Cancel As Integer)
ÖA> cmdSave.Enabled = True
ÖA> End Sub


Vadim
 
Personnally, I've always been against the use of transactions for long term
editing and every time I see someone implementing a cancel function for a
form by using a Rollback encased in a transaction make me grind my teeth.
The problems with scaling and performance degradation that this can lead to
are easy to guess.

However, even if I'm against their use in this context, this doesn't explain
why his particular piece of code is not working properly. Instead of using
one of the connection created by Access, he creates and use its own
connection (the line « ConnectionString = CurrentProject.Connection »
doesn't begin wit the SET command, so instead of reusing the
CurrentProject.Connection object, he's creating a new object using the
connection string of the CurrentProject.Connection object) so theoritically,
this should work.

However, by using this connection string, he's also using the special OLEDB
driver created for ADP and that is standing between the bound forms and
SQL-Server. Even with a separate connection string, the effect of using an
open transaction on this driver is totally undocumented by Microsoft and in
my opinion, totally unpredictable. It's clear in my opinion that even with
a separate connection, this driver will try to open and close its own
transactions while updating the database for saving the edited data on the
bound forms.

Maybe he could try following the @@transaction count on the server (inside a
stored procedure) to solve this problem but in my opinion, opening a direct
connection to the SQL-Server without using the connection string of the
CurrentProject.Connection object (to make sure that only the OLEDB provider
for SQL-Server is used, not that strange beast called the Microsoft OLEDB
provider for Access) and using unbound forms should be a much more safer
approach (albeit also more complicated but that's life) than the previously
posted code.

In the past, Microsoft has warned many times that trying to use transactions
with bound forms would have a high probability of problems and failures; I
don't see any reason to doubt their parole. If you use them and don't have
any problem, good for you but if you are unlucky, then you are on your own.
 
Hello Sylvain,

I think, in a nutshell, Access can be assumed incompatible with
transactions. For the simple reason: transactions and locking involve
server-based cursors. While Access (as well as vs.net) works with
client-based cursors. Client-based cursors create their own
pseudo-transaction; it may be good or bad, but it's totally different from
the server-based cursors, hence from locking, hence from transactions.

I totally agree, however, with the thought that "true" locking is hardly
compatible with interactive work. A user who is trying to edit a record
currently locked by someone else, will certainly assume that his application
or even computer has locked up. To be useful, the locking mechanism should
include some statement that would attempt to place the lock, and would be
asynchronous, so the user would be able to cancel the wait for the resource.

When I found that mentioned workaround with creating the true transaction by
using connection.execute "begin transaction", I actually opened support
ticket with Microsoft and asked if it's supported scenario (having pretty
good idea what would be the answer), and why begintrans does not work as
expected. The response was that, indeed, at some point there were plans to
make begintrans etc. fully working in ADP, but then it was stopped in the
middle, so the whole thing remains half-baked and undocumented.

In all new programming environments, Microsoft is actually pushing
client-based cursors, and there are results indeed: it looks like now most
developers don't even consider true locking. Recently, I tested this
hypothesis by asking moderately difficult locking-related question on
experts-exchange - nobody even tried to answer along the correct lines
(http://www.experts-exchange.com/Databases/Microsoft_SQL_Server/Q_22012456.html)
- though there are _very_ skilled sql programmers there. I won't be too
surprised if in some future version of sql server, user-controlled locking
will be abandoned as such.

Vadim Rapp

You wrote in conference microsoft.public.access.adp.sqlserver on Tue, 10
Oct 2006 00:18:26 -0400:

SL> Personnally, I've always been against the use of transactions for long
SL> term editing and every time I see someone implementing a cancel
SL> function for a form by using a Rollback encased in a transaction make
SL> me grind my teeth. The problems with scaling and performance
SL> degradation that this can lead to are easy to guess.

SL> However, even if I'm against their use in this context, this doesn't
SL> explain why his particular piece of code is not working properly.
SL> Instead of using one of the connection created by Access, he creates
SL> and use its own connection (the line « ConnectionString =
SL> CurrentProject.Connection » doesn't begin wit the SET command, so
SL> instead of reusing the CurrentProject.Connection object, he's creating
SL> a new object using the connection string of the
SL> CurrentProject.Connection object) so theoritically, this should work.

SL> However, by using this connection string, he's also using the special
SL> OLEDB driver created for ADP and that is standing between the bound
SL> forms and SQL-Server. Even with a separate connection string, the
SL> effect of using an open transaction on this driver is totally
SL> undocumented by Microsoft and in my opinion, totally unpredictable.
SL> It's clear in my opinion that even with a separate connection, this
SL> driver will try to open and close its own transactions while updating
SL> the database for saving the edited data on the bound forms.

SL> Maybe he could try following the @@transaction count on the server
SL> (inside a stored procedure) to solve this problem but in my opinion,
SL> opening a direct connection to the SQL-Server without using the
SL> connection string of the CurrentProject.Connection object (to make sure
SL> that only the OLEDB provider for SQL-Server is used, not that strange
SL> beast called the Microsoft OLEDB provider for Access) and using unbound
SL> forms should be a much more safer approach (albeit also more
SL> complicated but that's life) than the previously posted code.

SL> In the past, Microsoft has warned many times that trying to use
SL> transactions with bound forms would have a high probability of problems
SL> and failures; I don't see any reason to doubt their parole. If you use
SL> them and don't have any problem, good for you but if you are unlucky,
SL> then you are on your own.

SL> --
SL> Sylvain Lafontaine, ing.
SL> MVP - Technologies Virtual-PC
SL> E-mail: http://cerbermail.com/?QugbLEWINF

SL> SL>> Hello Ömer,
SL>>
SL>> you probably will be surprised, or maybe even won't believe, but the
SL>> code you posted could not work ever; at least, reliably. Unlike MDB,
SL>> with ADP, begintrans, committrans, and rollback are practically
SL>> ignored. See for example http://support.microsoft.com/kb/223213 - it's
easy to see that the results would
SL>> be unpredictable.
SL>>
SL>> Also see
SL>>
http://www.eggheadcafe.com/aspnet_answers/AccessadpSQLServer/Jan2006/post25750796.asp
-
SL>> Sylvain's comment. There's workaround, but it's unsupported and also
SL>> may bring unpredictable results - see my comment in the end of the
SL>> above page.
SL>>
SL>> From all my experience of working with ADP, the best results are
SL>> achieved by allowing Access to manipulate the data its own way, rather
SL>> than trying to force it to do what you want. For example, it's better
SL>> to specify recordsource for a form rather than set
SL>> me.recordset=<pre-created
recordset>>> - i.e. allow Access to build the recordset as it wants, rather

SL>> than force it to use yours. The path of forcing your way on Access is
SL>> paved with numerous hours of troubleshooting unpredictable behaviours
SL>> exactly like what you just encountered.
SL>>
SL>> The best tool for working with transactions and proper locking is VB6.
SL>> Everything else (Access, and VS.Net) is using client-based cursors.
SL>>
SL>> Vadim Rapp
SL>>
SL>> You wrote in conference microsoft.public.access.adp.sqlserver on Fri,
SL>> 6 Oct 2006 13:57:18 +0300:
SL>>
ÖA>>> Dear friends,
SL>>
ÖA>>> I encountered such a problem and do not know how to correct it:
SL>>
ÖA>>> I am using XP Professional, Office 2003 (SP2) and SQL2000
SL>>
ÖA>>> I'd like to use a transaction on one to many form. Specifically I
ÖA>>> have Bank(main form) and Branches (Subform) These are designed as
ÖA>>> bound forms to TB_BANK & TB_BRANCH tables respectively. However in
ÖA>>> order to use a transaction I open another connection and with this
ÖA>>> connection I start a transaction (Code as follows) at the open event
ÖA>>> of the main form. When user chooses to save whatever he has done with
ÖA>>> the form I commit otherwise rollback.
SL>>
ÖA>>> Up until this morning this approach was working perfectly. While
ÖA>>> debugging on the run Access hanged couple of times. Even though
ÖA>>> I recovered thru 'Compact & Repair Project' my ability to rollback
ÖA>>> has gone. Assuming that sth has happened to db I run SQL Querry
ÖA>>> analyzer and tried updating tables under transaction and no problem.
ÖA>>> I have other adp's using the very same approach they also work fine.
SL>>
ÖA>>> To eliminate the problem I created a new adp and copied only the
ÖA>>> above forms & code behind it and still the same thing. For any one
ÖA>>> who could propose sth the code is as follows:
SL>>
ÖA>>> Private mlngOpMode As openMode
ÖA>>> Private mcnnMain As New ADODB.Connection
ÖA>>> Private mrstBank As New ADODB.Recordset
ÖA>>> Private mrstBranch As New ADODB.Recordset
SL>>
ÖA>>> Private Sub Form_Open(Cancel As Integer)
ÖA>>> Dim strSqlMain As String
ÖA>>> Dim strSQLSub As String
ÖA>>> Dim strFilter As String
ÖA>>> Dim lngCallerForm As Long
ÖA>>> Dim strWhere As String
SL>>
ÖA>>> Dim varOparg As Variant
ÖA>>> Dim strNewData As String
SL>>
ÖA>>> ' Format of strOpenArg:
ÖA>>> ' openMode;NewData;CallerField;CallerForm;Filter
SL>>
ÖA>>> Me.ServerFilter = ""
SL>>
ÖA>>> varOparg = Split(Me.OpenArgs, ";")
ÖA>>> Me.Caption = CStr(varOparg(0)) ' Caption
ÖA>>> mlngOpMode = CLng(varOparg(1)) ' Open Mode
ÖA>>> strNewData = CStr(varOparg(2)) ' New Data
ÖA>>> ' Caller Field
ÖA>>> ' Caller Form
ÖA>>> strFilter = CStr(varOparg(5)) ' Filter
SL>>
ÖA>>> With mcnnMain
ÖA>>> .ConnectionString = CurrentProject.Connection
ÖA>>> .Open
ÖA>>> .BeginTrans
ÖA>>> End With
SL>>
ÖA>>> ' MainForm Recordsource
ÖA>>> strSqlMain = "SELECT * FROM AYZ_TB_BANK WHERE " & strFilter
ÖA>>> ' SubForm Recordsource
ÖA>>> strSQLSub = "SELECT * FROM AYZ_TB_BRANCH WHERE " & strFilter
SL>>
ÖA>>> mrstBank.Open strSqlMain, mcnnMain, adOpenKeyset,
ÖA>>> adLockOptimistic mrstBranch.Open strSQLSub, mcnnMain,
ÖA>>> adOpenKeyset,
SL>> adLockOptimistic
SL>>
ÖA>>> Set Me.Recordset = mrstBank
ÖA>>> Set Form_AYZ_SUBFRM_BRANCH.Recordset = mrstBranch
SL>>
ÖA>>> Private Sub cmdCancel_Click()
ÖA>>> Dim strMsg As String, userResponse As VbMsgBoxResult
ÖA>>> Dim strWhere As String
ÖA>>> Dim strSQL As String
SL>>
ÖA>>> On Error GoTo Err_cmdCancel_Click
SL>>
ÖA>>> If Me.cmdSave.Enabled Then
ÖA>>> strMsg = "Yaptýðýnýz deðiþiklikler iptal edilecektir."
ÖA>>> userResponse = DisplayMessage(strMsg, vbExclamation +
ÖA>>> vbOKCancel)
SL>>
ÖA>>> If userResponse = vbOK Then
ÖA>>> mcnnMain.RollbackTrans
ÖA>>> Else
ÖA>>> GoTo Exit_cmdCancel_Click
ÖA>>> End If
ÖA>>> End If
ÖA>>> DoCmd.Close acForm, Me.Name
SL>>
ÖA>>> Exit_cmdCancel_Click:
ÖA>>> Exit Sub
ÖA>>> Err_cmdCancel_Click:
ÖA>>> DisplayMessage Err.Number & ": " & Err.Description, vbCritical +
ÖA>>> vbOKOnly, "HATA!"
ÖA>>> Resume Exit_cmdCancel_Click
SL>>
ÖA>>> End Sub
SL>>
ÖA>>> Private Sub cmdSave_Click()
ÖA>>> Dim strMsg As String, lngBankID As Long, strWhere As String
ÖA>>> On Error GoTo Err_cmdSave_Click
SL>>
ÖA>>> If IsNull(Me.txtBankCode) Then
ÖA>>> strMsg = "'Banka Kodu' boþ olamaz."
ÖA>>> DisplayMessage strMsg, vbOKOnly + vbCritical, "UYARI!"
ÖA>>> Me.txtBankCode.SetFocus
ÖA>>> GoTo Exit_cmdSave_Click
ÖA>>> End If
SL>>
ÖA>>> mcnnMain.CommitTrans
SL>>
ÖA>>> DoCmd.Close acForm, Me.Name
ÖA>>> Exit_cmdSave_Click:
SL>>
ÖA>>> Exit Sub
ÖA>>> Err_cmdSave_Click:
ÖA>>> MsgBox Err.Description
ÖA>>> Resume Exit_cmdSave_Click
ÖA>>> End Sub
SL>>
ÖA>>> Private Sub Form_Close()
ÖA>>> Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID
ÖA>>> ' A little bit of house keeping
ÖA>>> Set mrstBank = Nothing
ÖA>>> Set mrstBranch = Nothing
ÖA>>> Set mcnnMain = Nothing
ÖA>>> End Sub
SL>>
ÖA>>> Private Sub Form_Dirty(Cancel As Integer)
ÖA>>> cmdSave.Enabled = True
ÖA>>> End Sub
SL>>
SL>> Vadim
SL>> ----------------------------------------
SL>> Vadim Rapp Consulting
SL>> SQL, Access, VB Solutions
SL>> 847-685-9073
SL>> www.vadimrapp.com


Vadim
 
A possible reason for "why begintrans does not work as expected." = adp opens multiple connections including (sometimes?) separate
connections for subforms

??
 
Transaction and locking are not necessary are properties of connections and
are not associated necessarily with server-based cursors. Opening a
served-based cursor will put a lock on the table but this is not the only
way of having a lock.

In fact, you can have an open lock on a row, page or table without having
any cursor at all! (This is why so many people have trouble with dead-locks
sometimes).
 
Hi,
Transaction and locking are not necessary are properties of
connections and are not associated necessarily with server-based
cursors. Opening a served-based cursor will put a lock on the table
but this is not the only way of having a lock.

In fact, you can have an open lock on a row, page or table without
having any cursor at all! (This is why so many people have trouble
with dead-locks sometimes).

maybe that PDF-book helps

Hands-On SQL Server 2000 : Troubleshooting Locking and Blocking
Author: Kalen Delaney

http://www.netimpress.com/shop/itembycat.asp?catid=1&currencies=USD
 
Malcolm;

where did you hear that from?

-Aaron


Malcolm said:
A possible reason for "why begintrans does not work as expected." = adp opens multiple connections including (sometimes?) separate
connections for subforms

??
 
Hello Sylvain,
You wrote in conference microsoft.public.access.adp.sqlserver on Wed, 11
Oct 2006 10:47:43 -0400:

SL> Transaction and locking are not necessary are properties of connections

Locking is a property of the recordset.

SL> and are not associated necessarily with server-based cursors.

I think they are. Client-based cursor, by definition, does the following:

1. download the records
2. edit the records "offline"
3. upload the records back to the database, with checking first if they have
not changed since (1)

During (2), the database does not "know" that the records are being edited,
there are no locks that would prevent others from touching the downloaded
records. The client may even disconnect from the database (disconnected
recordset). The database lock is established only during (1) and (2)

Server-based cursor, contrary, does establish database lock once the record
is edited.

SL> In fact, you can have an open lock on a row, page or table without
SL> having any cursor at all!

With recordsets? how? (I understand that it's possible by
non-recordset-returning operations like UPDATE TABLE, but we are talking
here about Access forms).

Vadim Rapp

SL> (This is why so many people have trouble with dead-locks sometimes).

SL> --
SL> Sylvain Lafontaine, ing.
SL> MVP - Technologies Virtual-PC
SL> E-mail: http://cerbermail.com/?QugbLEWINF

SL> SL>> Hello Sylvain,
SL>>
SL>> I think, in a nutshell, Access can be assumed incompatible with
SL>> transactions. For the simple reason: transactions and locking involve
SL>> server-based cursors. While Access (as well as vs.net) works with
SL>> client-based cursors. Client-based cursors create their own
SL>> pseudo-transaction; it may be good or bad, but it's totally different
SL>> from the server-based cursors, hence from locking, hence from
SL>> transactions.
SL>>
SL>> I totally agree, however, with the thought that "true" locking is
SL>> hardly compatible with interactive work. A user who is trying to edit
SL>> a record currently locked by someone else, will certainly assume that
SL>> his application or even computer has locked up. To be useful, the
SL>> locking mechanism should include some statement that would attempt to
SL>> place the lock, and would be asynchronous, so the user would be able
SL>> to cancel the wait for the resource.
SL>>
SL>> When I found that mentioned workaround with creating the true
SL>> transaction by using connection.execute "begin transaction", I
SL>> actually opened support ticket with Microsoft and asked if it's
SL>> supported scenario (having pretty good idea what would be the answer),
SL>> and why begintrans does not work as expected. The response was that,
SL>> indeed, at some point there were plans to make begintrans etc. fully
SL>> working in ADP, but then it was stopped in the middle, so the whole
SL>> thing remains half-baked and undocumented.
SL>>
SL>> In all new programming environments, Microsoft is actually pushing
SL>> client-based cursors, and there are results indeed: it looks like now
most
SL>> developers don't even consider true locking. Recently, I tested this
SL>> hypothesis by asking moderately difficult locking-related question on
SL>> experts-exchange - nobody even tried to answer along the correct lines
SL>> (http://www.experts-exchange.com/Databases/Microsoft_SQL_Server/Q_2201
SL>> 2456.html) - though there are _very_ skilled sql programmers there. I
SL>> won't be too surprised if in some future version of sql server,
SL>> user-controlled locking will be abandoned as such.
SL>>
SL>> Vadim Rapp
SL>>
SL>> You wrote in conference microsoft.public.access.adp.sqlserver on Tue,
SL>> 10 Oct 2006 00:18:26 -0400:
SL>>
SL>>> Personnally, I've always been against the use of transactions for
SL>>> long term editing and every time I see someone implementing a cancel
SL>>> function for a form by using a Rollback encased in a transaction make
SL>>> me grind my teeth. The problems with scaling and performance
SL>>> degradation that this can lead to are easy to guess.
SL>>
SL>>> However, even if I'm against their use in this context, this doesn't
SL>>> explain why his particular piece of code is not working properly.
SL>>> Instead of using one of the connection created by Access, he creates
SL>>> and use its own connection (the line « ConnectionString =
SL>>> CurrentProject.Connection » doesn't begin wit the SET command, so
SL>>> instead of reusing the CurrentProject.Connection object, he's
SL>>> creating a new object using the connection string of
SL>>> the CurrentProject.Connection object) so theoritically, this should
SL>>> work.
SL>>
SL>>> However, by using this connection string, he's also using the special
SL>>> OLEDB driver created for ADP and that is standing between the bound
SL>>> forms and SQL-Server. Even with a separate connection string, the
SL>>> effect of using an open transaction on this driver is totally
SL>>> undocumented by Microsoft and in my opinion, totally unpredictable.
SL>>> It's clear in my opinion that even with a separate connection, this
SL>>> driver will try to open and close its own transactions while updating
SL>>> the database for saving the edited data on the bound forms.
SL>>
SL>>> Maybe he could try following the @@transaction count on the server
SL>>> (inside a stored procedure) to solve this problem but in my opinion,
SL>>> opening a direct connection to the SQL-Server without using the
SL>>> connection string of the CurrentProject.Connection object (to make
SL>> sure
SL>>> that only the OLEDB provider for SQL-Server is used, not that strange
SL>>> beast called the Microsoft OLEDB provider for Access) and using
SL>> unbound
SL>>> forms should be a much more safer approach (albeit also more
SL>>> complicated but that's life) than the previously posted code.
SL>>
SL>>> In the past, Microsoft has warned many times that trying to use
SL>>> transactions with bound forms would have a high probability of
SL>> problems
SL>>> and failures; I don't see any reason to doubt their parole. If you
SL>> use
SL>>> them and don't have any problem, good for you but if you are unlucky,
SL>>> then you are on your own.
SL>>
SL>>> --
SL>>> Sylvain Lafontaine, ing.
SL>>> MVP - Technologies Virtual-PC
SL>>> E-mail: http://cerbermail.com/?QugbLEWINF
SL>>
SL>>> SL>>>> Hello Ömer,
SL>>>>
SL>>>> you probably will be surprised, or maybe even won't believe, but the
SL>>>> code you posted could not work ever; at least, reliably. Unlike MDB,
SL>>>> with ADP, begintrans, committrans, and rollback are practically
SL>>>> ignored. See for example http://support.microsoft.com/kb/223213 -
SL>> it's easy to see that the results would
SL>>>> be unpredictable.
SL>>>>
SL>>>> Also see
SL>>>>
SL>>
http://www.eggheadcafe.com/aspnet_answers/AccessadpSQLServer/Jan2006/post25750796.asp
-
SL>>>> Sylvain's comment. There's workaround, but it's unsupported and also
SL>>>> may bring unpredictable results - see my comment in the end of the
SL>>>> above page.
SL>>>>
SL>>>> From all my experience of working with ADP, the best results are
SL>>>> achieved by allowing Access to manipulate the data its own way,
SL>> rather
SL>>>> than trying to force it to do what you want. For example, it's
SL>>>> better to specify recordsource for a form rather than
SL>>>> set me.recordset=<pre-created
recordset>>>>> - i.e. allow Access to build the recordset as it wants,
SL>> rather
SL>>
SL>>>> than force it to use yours. The path of forcing your way on Access
SL>>>> is paved with numerous hours of troubleshooting unpredictable
SL>>>> behaviours exactly like what you just encountered.
SL>>>>
SL>>>> The best tool for working with transactions and proper locking is
SL>> VB6.
SL>>>> Everything else (Access, and VS.Net) is using client-based cursors.
SL>>>>
SL>>>> Vadim Rapp
SL>>>>
SL>>>> You wrote in conference microsoft.public.access.adp.sqlserver on
SL>> Fri,
SL>>>> 6 Oct 2006 13:57:18 +0300:
SL>>>>
ÖA>>>>> Dear friends,
SL>>>>
ÖA>>>>> I encountered such a problem and do not know how to correct it:
SL>>>>
ÖA>>>>> I am using XP Professional, Office 2003 (SP2) and SQL2000
SL>>>>
ÖA>>>>> I'd like to use a transaction on one to many form. Specifically I
ÖA>>>>> have Bank(main form) and Branches (Subform) These are designed as
ÖA>>>>> bound forms to TB_BANK & TB_BRANCH tables respectively. However in
ÖA>>>>> order to use a transaction I open another connection and with this
ÖA>>>>> connection I start a transaction (Code as follows) at the open
ÖA>>>>> event of the main form. When user chooses to save whatever he has
ÖA>>>>> done
SL>> with
ÖA>>>>> the form I commit otherwise rollback.
SL>>>>
ÖA>>>>> Up until this morning this approach was working perfectly. While
ÖA>>>>> debugging on the run Access hanged couple of times. Even though
ÖA>>>>> I recovered thru 'Compact & Repair Project' my ability to rollback
ÖA>>>>> has gone. Assuming that sth has happened to db I run SQL Querry
ÖA>>>>> analyzer and tried updating tables under transaction and no
ÖA>>>>> problem. I have other adp's using the very same approach they also
ÖA>>>>> work fine.
SL>>>>
ÖA>>>>> To eliminate the problem I created a new adp and copied only the
ÖA>>>>> above forms & code behind it and still the same thing. For any one
ÖA>>>>> who could propose sth the code is as follows:
SL>>>>
ÖA>>>>> Private mlngOpMode As openMode
ÖA>>>>> Private mcnnMain As New ADODB.Connection
ÖA>>>>> Private mrstBank As New ADODB.Recordset
ÖA>>>>> Private mrstBranch As New ADODB.Recordset
SL>>>>
ÖA>>>>> Private Sub Form_Open(Cancel As Integer)
ÖA>>>>> Dim strSqlMain As String
ÖA>>>>> Dim strSQLSub As String
ÖA>>>>> Dim strFilter As String
ÖA>>>>> Dim lngCallerForm As Long
ÖA>>>>> Dim strWhere As String
SL>>>>
ÖA>>>>> Dim varOparg As Variant
ÖA>>>>> Dim strNewData As String
SL>>>>
ÖA>>>>> ' Format of strOpenArg:
ÖA>>>>> ' openMode;NewData;CallerField;CallerForm;Filter
SL>>>>
ÖA>>>>> Me.ServerFilter = ""
SL>>>>
ÖA>>>>> varOparg = Split(Me.OpenArgs, ";")
ÖA>>>>> Me.Caption = CStr(varOparg(0)) ' Caption
ÖA>>>>> mlngOpMode = CLng(varOparg(1)) ' Open Mode
ÖA>>>>> strNewData = CStr(varOparg(2)) ' New Data
ÖA>>>>> ' Caller Field
ÖA>>>>> ' Caller Form
ÖA>>>>> strFilter = CStr(varOparg(5)) ' Filter
SL>>>>
ÖA>>>>> With mcnnMain
ÖA>>>>> .ConnectionString = CurrentProject.Connection
ÖA>>>>> .Open
ÖA>>>>> .BeginTrans
ÖA>>>>> End With
SL>>>>
ÖA>>>>> ' MainForm Recordsource
ÖA>>>>> strSqlMain = "SELECT * FROM AYZ_TB_BANK WHERE " & strFilter
ÖA>>>>> ' SubForm Recordsource
ÖA>>>>> strSQLSub = "SELECT * FROM AYZ_TB_BRANCH WHERE " & strFilter
SL>>>>
ÖA>>>>> mrstBank.Open strSqlMain, mcnnMain, adOpenKeyset,
ÖA>>>>> adLockOptimistic mrstBranch.Open strSQLSub, mcnnMain,
ÖA>>>>> adOpenKeyset,
SL>>>> adLockOptimistic
SL>>>>
ÖA>>>>> Set Me.Recordset = mrstBank
ÖA>>>>> Set Form_AYZ_SUBFRM_BRANCH.Recordset = mrstBranch
SL>>>>
ÖA>>>>> Private Sub cmdCancel_Click()
ÖA>>>>> Dim strMsg As String, userResponse As VbMsgBoxResult
ÖA>>>>> Dim strWhere As String
ÖA>>>>> Dim strSQL As String
SL>>>>
ÖA>>>>> On Error GoTo Err_cmdCancel_Click
SL>>>>
ÖA>>>>> If Me.cmdSave.Enabled Then
ÖA>>>>> strMsg = "Yaptýðýnýz deðiþiklikler iptal edilecektir."
ÖA>>>>> userResponse = DisplayMessage(strMsg, vbExclamation +
ÖA>>>>> vbOKCancel)
SL>>>>
ÖA>>>>> If userResponse = vbOK Then
ÖA>>>>> mcnnMain.RollbackTrans
ÖA>>>>> Else
ÖA>>>>> GoTo Exit_cmdCancel_Click
ÖA>>>>> End If
ÖA>>>>> End If
ÖA>>>>> DoCmd.Close acForm, Me.Name
SL>>>>
ÖA>>>>> Exit_cmdCancel_Click:
ÖA>>>>> Exit Sub
ÖA>>>>> Err_cmdCancel_Click:
ÖA>>>>> DisplayMessage Err.Number & ": " & Err.Description, vbCritical
ÖA>>>>> + vbOKOnly, "HATA!" Resume Exit_cmdCancel_Click
SL>>>>
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub cmdSave_Click()
ÖA>>>>> Dim strMsg As String, lngBankID As Long, strWhere As String
ÖA>>>>> On Error GoTo Err_cmdSave_Click
SL>>>>
ÖA>>>>> If IsNull(Me.txtBankCode) Then
ÖA>>>>> strMsg = "'Banka Kodu' boþ olamaz."
ÖA>>>>> DisplayMessage strMsg, vbOKOnly + vbCritical, "UYARI!"
ÖA>>>>> Me.txtBankCode.SetFocus
ÖA>>>>> GoTo Exit_cmdSave_Click
ÖA>>>>> End If
SL>>>>
ÖA>>>>> mcnnMain.CommitTrans
SL>>>>
ÖA>>>>> DoCmd.Close acForm, Me.Name
ÖA>>>>> Exit_cmdSave_Click:
SL>>>>
ÖA>>>>> Exit Sub
ÖA>>>>> Err_cmdSave_Click:
ÖA>>>>> MsgBox Err.Description
ÖA>>>>> Resume Exit_cmdSave_Click
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub Form_Close()
ÖA>>>>> Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID
ÖA>>>>> ' A little bit of house keeping
ÖA>>>>> Set mrstBank = Nothing
ÖA>>>>> Set mrstBranch = Nothing
ÖA>>>>> Set mcnnMain = Nothing
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub Form_Dirty(Cancel As Integer)
ÖA>>>>> cmdSave.Enabled = True
ÖA>>>>> End Sub
SL>>>>
SL>>>> Vadim
SL>>>> ----------------------------------------
SL>>>> Vadim Rapp Consulting
SL>>>> SQL, Access, VB Solutions
SL>>>> 847-685-9073
SL>>>> www.vadimrapp.com
SL>>
SL>> Vadim
SL>> ----------------------------------------
SL>> Vadim Rapp Consulting
SL>> SQL, Access, VB Solutions
SL>> 847-685-9073
SL>> www.vadimrapp.com


Vadim
 
Hello Malcolm,
You wrote in conference microsoft.public.access.adp.sqlserver on Wed, 11
Oct 2006 09:24:49 -0500:

MC> A possible reason for "why begintrans does not work as expected." =
MC> adp opens multiple connections including (sometimes?) separate
MC> connections for subforms

No, I don't think it's the reason. Even if you have a single form without
subforms and without comboboxes (another case of separate connection),
begintrans/committrans still won't work. I think the main reason is the
client-side cursors used by the form's recordset, and their philosophy
"download/work/upload" rather than "reserve/work/release" implied by
transactions.

MC> ??

MC>> Hello Sylvain,
MC>>
MC>> I think, in a nutshell, Access can be assumed incompatible with
MC>> transactions. For the simple reason: transactions and locking involve
MC>> server-based cursors. While Access (as well as vs.net) works with
MC>> client-based cursors. Client-based cursors create their own
MC>> pseudo-transaction; it may be good or bad, but it's totally different
MC>> from the server-based cursors, hence from locking, hence from
MC>> transactions.
MC>>
MC>> I totally agree, however, with the thought that "true" locking is
MC>> hardly compatible with interactive work. A user who is trying to edit
MC>> a record currently locked by someone else, will certainly assume that
MC>> his application or even computer has locked up. To be useful, the
MC>> locking mechanism should include some statement that would attempt to
MC>> place the lock, and would be asynchronous, so the user would be able
MC>> to cancel the wait for the resource.
MC>>
MC>> When I found that mentioned workaround with creating the true
MC>> transaction by using connection.execute "begin transaction", I
MC>> actually opened support ticket with Microsoft and asked if it's
MC>> supported scenario (having pretty good idea what would be the answer),
MC>> and why begintrans does not work as expected. The response was that,
MC>> indeed, at some point there were plans to make begintrans etc. fully
MC>> working in ADP, but then it was stopped in the middle, so the whole
MC>> thing remains half-baked and undocumented.
MC>>
MC>> In all new programming environments, Microsoft is actually pushing
MC>> client-based cursors, and there are results indeed: it looks like now
most
MC>> developers don't even consider true locking. Recently, I tested this
MC>> hypothesis by asking moderately difficult locking-related question on
MC>> experts-exchange - nobody even tried to answer along the correct lines
MC>> (http://www.experts-exchange.com/Databases/Microsoft_SQL_Server/Q_2201
MC>> 2456.html) - though there are _very_ skilled sql programmers there. I
MC>> won't be too surprised if in some future version of sql server,
MC>> user-controlled locking will be abandoned as such.
MC>>
MC>> Vadim Rapp
MC>>
MC>> You wrote in conference microsoft.public.access.adp.sqlserver on Tue,
MC>> 10 Oct 2006 00:18:26 -0400:
MC>>
SL>>> Personnally, I've always been against the use of transactions for
SL>>> long term editing and every time I see someone implementing a cancel
SL>>> function for a form by using a Rollback encased in a transaction make
SL>>> me grind my teeth. The problems with scaling and performance
SL>>> degradation that this can lead to are easy to guess.
MC>>
SL>>> However, even if I'm against their use in this context, this doesn't
SL>>> explain why his particular piece of code is not working properly.
SL>>> Instead of using one of the connection created by Access, he creates
SL>>> and use its own connection (the line « ConnectionString =
SL>>> CurrentProject.Connection » doesn't begin wit the SET command, so
SL>>> instead of reusing the CurrentProject.Connection object, he's
SL>>> creating a new object using the connection string of
SL>>> the CurrentProject.Connection object) so theoritically, this should
SL>>> work.
MC>>
SL>>> However, by using this connection string, he's also using the special
SL>>> OLEDB driver created for ADP and that is standing between the bound
SL>>> forms and SQL-Server. Even with a separate connection string, the
SL>>> effect of using an open transaction on this driver is totally
SL>>> undocumented by Microsoft and in my opinion, totally unpredictable.
SL>>> It's clear in my opinion that even with a separate connection, this
SL>>> driver will try to open and close its own transactions while updating
SL>>> the database for saving the edited data on the bound forms.
MC>>
SL>>> Maybe he could try following the @@transaction count on the server
SL>>> (inside a stored procedure) to solve this problem but in my opinion,
SL>>> opening a direct connection to the SQL-Server without using the
SL>>> connection string of the CurrentProject.Connection object (to make
SL>>> sure that only the OLEDB provider for SQL-Server is used, not that
SL>>> strange beast called the Microsoft OLEDB provider for Access) and
SL>>> using unbound forms should be a much more safer approach (albeit also
SL>>> more complicated but that's life) than the previously posted code.
MC>>
SL>>> In the past, Microsoft has warned many times that trying to use
SL>>> transactions with bound forms would have a high probability of
SL>>> problems and failures; I don't see any reason to doubt their parole.
SL>>> If you use them and don't have any problem, good for you but if you
SL>>> are unlucky, then you are on your own.
MC>>
SL>>> --
SL>>> Sylvain Lafontaine, ing.
SL>>> MVP - Technologies Virtual-PC
SL>>> E-mail: http://cerbermail.com/?QugbLEWINF
MC>>
SL>>> SL>>>> Hello Ömer,
SL>>>>
SL>>>> you probably will be surprised, or maybe even won't believe, but the
SL>>>> code you posted could not work ever; at least, reliably. Unlike MDB,
SL>>>> with ADP, begintrans, committrans, and rollback are practically
SL>>>> ignored. See for example http://support.microsoft.com/kb/223213 -
it's
MC>> easy to see that the results would
SL>>>> be unpredictable.
SL>>>>
SL>>>> Also see
SL>>>>
MC>> http://www.eggheadcafe.com/aspnet_answers/AccessadpSQLServer/Jan2006/post25750796.asp
MC>> -
SL>>>> Sylvain's comment. There's workaround, but it's unsupported and also
SL>>>> may bring unpredictable results - see my comment in the end of the
SL>>>> above page.
SL>>>>
SL>>>> From all my experience of working with ADP, the best results are
SL>>>> achieved by allowing Access to manipulate the data its own way,
SL>>>> rather than trying to force it to do what you want. For example,
SL>>>> it's better to specify recordsource for a form rather than
SL>>>> set me.recordset=<pre-created
recordset>>>>> - i.e. allow Access to build the recordset as it wants,
recordset>>>>> rather
MC>>
SL>>>> than force it to use yours. The path of forcing your way on Access
SL>>>> is paved with numerous hours of troubleshooting unpredictable
SL>>>> behaviours exactly like what you just encountered.
SL>>>>
SL>>>> The best tool for working with transactions and proper locking is
SL>>>> VB6. Everything else (Access, and VS.Net) is using client-based
SL>>>> cursors.
SL>>>>
SL>>>> Vadim Rapp
SL>>>>
SL>>>> You wrote in conference microsoft.public.access.adp.sqlserver on
SL>>>> Fri, 6 Oct 2006 13:57:18 +0300:
SL>>>>
ÖA>>>>> Dear friends,
SL>>>>
ÖA>>>>> I encountered such a problem and do not know how to correct it:
SL>>>>
ÖA>>>>> I am using XP Professional, Office 2003 (SP2) and SQL2000
SL>>>>
ÖA>>>>> I'd like to use a transaction on one to many form. Specifically I
ÖA>>>>> have Bank(main form) and Branches (Subform) These are designed as
ÖA>>>>> bound forms to TB_BANK & TB_BRANCH tables respectively. However in
ÖA>>>>> order to use a transaction I open another connection and with this
ÖA>>>>> connection I start a transaction (Code as follows) at the open
ÖA>>>>> event of the main form. When user chooses to save whatever he has
ÖA>>>>> done with the form I commit otherwise rollback.
SL>>>>
ÖA>>>>> Up until this morning this approach was working perfectly. While
ÖA>>>>> debugging on the run Access hanged couple of times. Even though
ÖA>>>>> I recovered thru 'Compact & Repair Project' my ability to rollback
ÖA>>>>> has gone. Assuming that sth has happened to db I run SQL Querry
ÖA>>>>> analyzer and tried updating tables under transaction and no
ÖA>>>>> problem. I have other adp's using the very same approach they also
ÖA>>>>> work fine.
SL>>>>
ÖA>>>>> To eliminate the problem I created a new adp and copied only the
ÖA>>>>> above forms & code behind it and still the same thing. For any one
ÖA>>>>> who could propose sth the code is as follows:
SL>>>>
ÖA>>>>> Private mlngOpMode As openMode
ÖA>>>>> Private mcnnMain As New ADODB.Connection
ÖA>>>>> Private mrstBank As New ADODB.Recordset
ÖA>>>>> Private mrstBranch As New ADODB.Recordset
SL>>>>
ÖA>>>>> Private Sub Form_Open(Cancel As Integer)
ÖA>>>>> Dim strSqlMain As String
ÖA>>>>> Dim strSQLSub As String
ÖA>>>>> Dim strFilter As String
ÖA>>>>> Dim lngCallerForm As Long
ÖA>>>>> Dim strWhere As String
SL>>>>
ÖA>>>>> Dim varOparg As Variant
ÖA>>>>> Dim strNewData As String
SL>>>>
ÖA>>>>> ' Format of strOpenArg:
ÖA>>>>> ' openMode;NewData;CallerField;CallerForm;Filter
SL>>>>
ÖA>>>>> Me.ServerFilter = ""
SL>>>>
ÖA>>>>> varOparg = Split(Me.OpenArgs, ";")
ÖA>>>>> Me.Caption = CStr(varOparg(0)) ' Caption
ÖA>>>>> mlngOpMode = CLng(varOparg(1)) ' Open Mode
ÖA>>>>> strNewData = CStr(varOparg(2)) ' New Data
ÖA>>>>> ' Caller Field
ÖA>>>>> ' Caller Form
ÖA>>>>> strFilter = CStr(varOparg(5)) ' Filter
SL>>>>
ÖA>>>>> With mcnnMain
ÖA>>>>> .ConnectionString = CurrentProject.Connection
ÖA>>>>> .Open
ÖA>>>>> .BeginTrans
ÖA>>>>> End With
SL>>>>
ÖA>>>>> ' MainForm Recordsource
ÖA>>>>> strSqlMain = "SELECT * FROM AYZ_TB_BANK WHERE " & strFilter
ÖA>>>>> ' SubForm Recordsource
ÖA>>>>> strSQLSub = "SELECT * FROM AYZ_TB_BRANCH WHERE " & strFilter
SL>>>>
ÖA>>>>> mrstBank.Open strSqlMain, mcnnMain, adOpenKeyset,
ÖA>>>>> adLockOptimistic mrstBranch.Open strSQLSub, mcnnMain,
ÖA>>>>> adOpenKeyset,
SL>>>> adLockOptimistic
SL>>>>
ÖA>>>>> Set Me.Recordset = mrstBank
ÖA>>>>> Set Form_AYZ_SUBFRM_BRANCH.Recordset = mrstBranch
SL>>>>
ÖA>>>>> Private Sub cmdCancel_Click()
ÖA>>>>> Dim strMsg As String, userResponse As VbMsgBoxResult
ÖA>>>>> Dim strWhere As String
ÖA>>>>> Dim strSQL As String
SL>>>>
ÖA>>>>> On Error GoTo Err_cmdCancel_Click
SL>>>>
ÖA>>>>> If Me.cmdSave.Enabled Then
ÖA>>>>> strMsg = "Yaptýðýnýz deðiþiklikler iptal edilecektir."
ÖA>>>>> userResponse = DisplayMessage(strMsg, vbExclamation +
ÖA>>>>> vbOKCancel)
SL>>>>
ÖA>>>>> If userResponse = vbOK Then
ÖA>>>>> mcnnMain.RollbackTrans
ÖA>>>>> Else
ÖA>>>>> GoTo Exit_cmdCancel_Click
ÖA>>>>> End If
ÖA>>>>> End If
ÖA>>>>> DoCmd.Close acForm, Me.Name
SL>>>>
ÖA>>>>> Exit_cmdCancel_Click:
ÖA>>>>> Exit Sub
ÖA>>>>> Err_cmdCancel_Click:
ÖA>>>>> DisplayMessage Err.Number & ": " & Err.Description, vbCritical
ÖA>>>>> + vbOKOnly, "HATA!" Resume Exit_cmdCancel_Click
SL>>>>
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub cmdSave_Click()
ÖA>>>>> Dim strMsg As String, lngBankID As Long, strWhere As String
ÖA>>>>> On Error GoTo Err_cmdSave_Click
SL>>>>
ÖA>>>>> If IsNull(Me.txtBankCode) Then
ÖA>>>>> strMsg = "'Banka Kodu' boþ olamaz."
ÖA>>>>> DisplayMessage strMsg, vbOKOnly + vbCritical, "UYARI!"
ÖA>>>>> Me.txtBankCode.SetFocus
ÖA>>>>> GoTo Exit_cmdSave_Click
ÖA>>>>> End If
SL>>>>
ÖA>>>>> mcnnMain.CommitTrans
SL>>>>
ÖA>>>>> DoCmd.Close acForm, Me.Name
ÖA>>>>> Exit_cmdSave_Click:
SL>>>>
ÖA>>>>> Exit Sub
ÖA>>>>> Err_cmdSave_Click:
ÖA>>>>> MsgBox Err.Description
ÖA>>>>> Resume Exit_cmdSave_Click
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub Form_Close()
ÖA>>>>> Form_AYZ_FRM_BANKBR.txtFindCriteria = Me.txtBankID
ÖA>>>>> ' A little bit of house keeping
ÖA>>>>> Set mrstBank = Nothing
ÖA>>>>> Set mrstBranch = Nothing
ÖA>>>>> Set mcnnMain = Nothing
ÖA>>>>> End Sub
SL>>>>
ÖA>>>>> Private Sub Form_Dirty(Cancel As Integer)
ÖA>>>>> cmdSave.Enabled = True
ÖA>>>>> End Sub
SL>>>>
SL>>>> Vadim
SL>>>> ----------------------------------------
SL>>>> Vadim Rapp Consulting
SL>>>> SQL, Access, VB Solutions
SL>>>> 847-685-9073
SL>>>> www.vadimrapp.com
MC>>
MC>> Vadim
MC>> ----------------------------------------
MC>> Vadim Rapp Consulting
MC>> SQL, Access, VB Solutions
MC>> 847-685-9073
MC>> www.vadimrapp.com
MC>>

Vadim
 
Sorry, but after re-reading myself, I see that what I wrote is not clear at
all; it should have been:

Transaction and locking are not properties of recordsets but are properties
of connections and as such, they are
not necessarily associated with server-based cursors or with client-side or
server-side recordsets. Opening a served-based cursor will put a lock on
the table but this is not the only way of having a lock; as in fact you can
even have a lock without any cursor at all.

If you want to, you can have a client based cursor that will lock the
records on the server. The only restriction would be that the recordset
must remains connected because locks on SQL-Server are always associated
with an open connection. If a connection is closed, any opened lock are
released and any uncommitted transaction are rolled back automatically.

If Access doesn't use lock with its recordsets, it's not because of a
technical impossibility but simply because it's not programmed to act in
this way. (Doing so would be a major performance sink but that's another
story). Don't confuse the capabilities of Access/ADP with the capabilities
of ADO or of SQL-Server.

When using a JET database backend, you can easily have a recordset with
pessimistic locking in Access but this is not because of a technical
superiority of JET; it's simply because MS doesn't feel that any performance
penalty can be considered as important when you are using JET as the
backend. If you are using JET, than you are not expected to consider that
performance might be important.
 
Hello Sylvain,
You wrote in conference microsoft.public.access.adp.sqlserver on Sat, 14
Oct 2006 00:12:45 -0400:

SL> If you want to, you can have a client based cursor that will lock the
SL> records on the server.

could you give a coding example?

Vadim Rapp
 
Coding example? You don't have to go to far, as the original post is itself
an example on how to open a transaction from ADO. Once a transaction is
opened, SQL-Server won't make any difference in the way it will deal with
implicit and explicit locks whatever the type of the client used at the
other side of the connection. If you use the Serializable or the Repeatable
Read isolation levels or if you make a select query with an exclusive lock
such as UPDLOCK, it will keep it until the end of the transaction and that's
it. What you are doing in the meantime with the resultset at the client
side is of no concern to SQL-Server.

I agree that by using the connection string of CurrentProject.Connection,
the code posted in the OP get entangled by the Microsoft Access OLEDB
Provider 10.0; however, this doesn't change anything to the fact that the
connection object of ADO has full support for transactions and isolation
levels.

I'm not sure if you want me to show here some basic examples about locking
on the SQL-Server, as you probably already have an in-depth knowledge of
these concepts but even if you don't have one, the fact that they are so
poorly supported in ADP or more precisely, not supported at all, make this
newsgroup a bad place to start a discussion about them.
 
I find this hilarious

If you are using JET, than you are not expected to consider that
performance might be important.


I mean seriously.. If Microsoft really feels that way then they need to
**** themselves.

HIGH-PERFORMANCE, SIMPLE DATA ENTRY AND REPORTING.
That is what we DEMAND.

-Aaron
 
Back
Top