I'm just going to remind you -- because it bugs me so much --
that dao linked table transactions are broken against sql server
in Jet 4. Because DAO maintains a connection pool and in
Jet 4, the connections block each other.
Maybe what you are saying explains the problem I am seeing with the
following piece of code.
The line marked >>> hangs indefinitely.
When I check Locks & Processes in SQL Enterprise manager I find that
the select query is blocked by "sp_execute;1"
The problem only occurs when I wrap a BeginTrans and CommitTrans
around the updates.
I'm guessing that the problem is occuring beause I am accessing the
same table using several different recordsets.
The code below is horrific (and I don't expect anyone to wade though
it) - I just about had blood coming out of my ears by the time I
finished writing it.
Private Sub Form_AfterUpdate()
Dim lngTemplateBookingId As Long
Dim lngParticipantId As Long
Dim rs As Recordset
Dim strSQL As String
Dim rsCS As Recordset
Dim lngSessionBookingId As Long
Dim CompId As Long
Dim boolInclude As Boolean
Dim boolExclude As Boolean
Dim varPrompt As Variant
Dim strWhere As String
Dim boolAlreadyNone As Boolean
Dim boolNullComp As Boolean
Dim lngBackwardAuditLinkId As Long
Dim boolWholeChange As Boolean
Dim frm As Form
Dim rsComp As Recordset
Dim boolAnyCompLeft As Boolean
Dim rsEL As Recordset
Dim rs2 As Recordset
Dim rsCS2 As Recordset
Dim rsCS3 As Recordset
Dim wrkDefault As Workspace
Dim strError As String
Dim rsDel As Recordset
boolWholeChange = False
lngTemplateBookingId = Me.Parent![TemplateBookingId]
lngParticipantId = Me.Parent![ParticipantID]
lngSessionBookingId = Me.SessionBookingId
lngCompId = Me.CompId
boolInclude = Me.Include
varPrompt = Me.Parent!ParticipantBookingSubCtl.Form![Prompt]
'
' Get any of the tblBkSessionCompParticipantLink records
'
strSQL = "Select * from tblBkSessionCompParticipantLink " & _
"WHERE ([TemplateBookingId] = " & lngTemplateBookingId &
") " & _
"AND ([ParticipantId] = " & lngParticipantId & ")"
Set wrkDefault = DBEngine.Workspaces(0)
'
' Beginning of Transaction
'
wrkDefault.BeginTrans
On Error GoTo CompSelectErr
Set rs = CurrentDb().OpenRecordset(strSQL, dbOpenDynaset,
dbSeeChanges)
'
' check no comps left
'
If rs.BOF And rs.EOF Then
boolWholeChange = True 'going from none to part
If boolInclude Then
rs.AddNew
rs![SessionBookingId] = lngSessionBookingId
rs![TemplateBookingId] = lngTemplateBookingId
rs![CompId] = lngCompId
rs![ParticipantID] = lngParticipantId
If IsNull(varPrompt) = False Then
rs![Prompt] = varPrompt
End If
rs.Update
rs.Close
Set rs = Nothing
End If
Exit Sub
Else
boolNullComp = IsNull(rs![CompId])
lngBackwardAuditLinkId = Nz(rs!BackwardAuditLinkId, 0) 'grab its
backward audit link if it has one
End If
'
' got just one record with a null CompId
' or multiple detailed records already ?
'
'just have a single tblBkSessionCompParticipantLink record with
CompId null (ie means include all session comps)
If boolNullComp Then
'delete the single null record
rs.Delete
boolWholeChange = True 'going from whole to part
If boolInclude Then 'we just ticked the box
'should not get here
Else 'we just unticked the box
'having deleted the single tblBkSessionCompParticipantLink
record with the null CompId
'need to now add in multiple records for every Session, Comp
except the specific one we just unticked
Set rsCS = CurrentDb().OpenRecordset("tmpCompSelect")
Do While Not rsCS.EOF
boolExclude = (rsCS!SessionBookingId =
lngSessionBookingId) And (rsCS!CompId = lngCompId)
If Not boolExclude Then
rs.AddNew
rs![SessionBookingId] = rsCS![SessionBookingId]
rs![TemplateBookingId] = lngTemplateBookingId
rs![CompId] = rsCS![CompId]
rs![ParticipantID] = lngParticipantId
If IsNull(varPrompt) = False Then
rs![Prompt] = varPrompt
End If
rs!BackwardAuditLinkId = lngBackwardAuditLinkId
'attempt to patch up backward link if it exists
rs.Update
End If
rsCS.MoveNext
Loop
rsCS.Close
Set rsCS = Nothing
'need to now add in multiple records for every comp element
except the specific comp one we just unticked
'need to examine boolAnyCompLeft - just because we unticked
the competency once it is not necessarily completely gone
'it could still exist in another session
Set rsCS2 = CurrentDb().OpenRecordset("select * from
tmpCompSelect where (tmpCompSelect.[CompId] = " & lngCompId & ") and
(tmpCompSelect.[Include] = True)")
boolAnyCompLeft = Not (rsCS2.BOF And rsCS2.EOF)
rsCS2.Close
Set rsCS2 = Nothing
Set rsEL = CurrentDb().OpenRecordset("tmpElementSelect")
If Not (rsEL.BOF And rsEL.EOF) Then
If boolAnyCompLeft = False Then
Do While Not rsEL.EOF
If rsEL!CompId = lngCompId Then
rsEL.Edit
rsEL![Include] = False
rsEL.Update
End If
rsEL.MoveNext
Loop
End If
rsEL.MoveFirst
Set rs2 =
CurrentDb().OpenRecordset("tblBkCompElementParticipantLink",
dbOpenDynaset, dbSeeChanges)
Do While Not rsEL.EOF
If rsEL![Include] = True Then
rs2.AddNew
rs2![TemplateBookingId] = lngTemplateBookingId
rs2![ParticipantID] = lngParticipantId
rs2![CompElementId] = rsEL![CompElementId]
rs2.Update
End If
rsEL.MoveNext
Loop
rs2.Close
Set rs2 = Nothing
End If
rsEL.Close
Set rsEL = Nothing
End If
'have multiple tblBkSessionCompParticipantLink records already (ie
means at least one session comp has been unticked)
Else
If boolInclude Then 'we just ticked the box
rs.AddNew
rs![SessionBookingId] = lngSessionBookingId
rs![TemplateBookingId] = lngTemplateBookingId
rs![CompId] = lngCompId
rs![ParticipantID] = lngParticipantId
If IsNull(varPrompt) = False Then
rs![Prompt] = varPrompt
End If
rs!BackwardAuditLinkId = lngBackwardAuditLinkId
rs.Update
'
' If we just ticked a box - have we managed to retick all of
them ?
'
Set rsCS = CurrentDb().OpenRecordset("select * from
tmpCompSelect where [Include] = false")
Set rsCS3 = CurrentDb().OpenRecordset("select * from
tmpElementSelect where [Include] = false")
If (rsCS.BOF And rsCS.EOF) And (rsCS3.BOF And rsCS3.EOF) Then
'everything is ticked
'so delete all the little
tblBkSessionCompParticipantLink,tblBkCompElementParticipantLink
records for this person, this booking
boolWholeChange = True 'going from part to Whole
strSQL = "select * from tblBkSessionCompParticipantLink "
& _
"WHERE ([TemplateBookingId] = " &
lngTemplateBookingId & ") " & _
"AND ([ParticipantId] = " & lngParticipantId &
")"Do While Not rsDel.EOF
rsDel.Delete
rsDel.MoveNext
Loop
rsDel.Close
strSQL = "select * from tblBkCompElementParticipantLink "
& _
"WHERE ([TemplateBookingId] = " &
lngTemplateBookingId & ") " & _
"AND ([ParticipantId] = " & lngParticipantId &
")"
Set rsDel = CurrentDb().OpenRecordset(strSQL,
dbOpenDynaset, dbSeeChanges)
Do While Not rsDel.EOF
rsDel.Delete
rsDel.MoveNext
Loop
rsDel.Close
Set rsDel = Nothing
'
'now add back in a single tblBkSessionCompParticipantLink
record with null CompId
'
Set rs =
CurrentDb().OpenRecordset("tblBkSessionCompParticipantLink",
dbOpenDynaset, dbSeeChanges)
rs.AddNew
rs![TemplateBookingId] = lngTemplateBookingId
rs![ParticipantID] = lngParticipantId
If IsNull(varPrompt) = False Then
rs![Prompt] = varPrompt
End If
rs!BackwardAuditLinkId = lngBackwardAuditLinkId
rs.Update
End If
rsCS.Close
Set rsCS = Nothing
rsCS3.Close
Set rsCS3 = Nothing
Else 'we just unticked the box
strWhere = "([SessionBookingId] = " & lngSessionBookingId &
") AND ([CompId] = " & lngCompId & ")"
rs.FindFirst strWhere
If rs.NoMatch Then
MsgBox "Something wrong - cannot find
tblBkSessionCompParticipantLink record being unticked"
End If
rs.Delete
'
' any of this comp left at all
'
Set rsCS2 = CurrentDb().OpenRecordset("select * from
tmpCompSelect where (tmpCompSelect.[CompId] = " & lngCompId & ") and
(tmpCompSelect.[Include] = True)")
boolAnyCompLeft = Not (rsCS2.BOF And rsCS2.EOF)
rsCS2.Close
Set rsCS2 = Nothing
'
' if none of this comp left then
' untick any of its elements
'
If boolAnyCompLeft = False Then
Set rsEL = CurrentDb().OpenRecordset("tmpElementSelect")
If Not (rsEL.BOF And rsEL.EOF) Then
Set rs2 =
CurrentDb().OpenRecordset("tblBkCompElementParticipantLink",
dbOpenDynaset, dbSeeChanges)
Do While Not rsEL.EOF
If rsEL!CompId = lngCompId Then
rsEL.Edit
rsEL![Include] = False
lngCompElementId = rsEL![CompElementId]
rsEL.Update
strWhere = "([TemplateBookingId] = " &
lngTemplateBookingId & ") " & _
" AND ([CompElementId] = " &
lngCompElementId & ") " & _
" AND ([ParticipantId] = " &
lngParticipantId & ")"
rs2.FindFirst strWhere
If Not rs2.NoMatch Then
rs2.Delete
End If
End If
rsEL.MoveNext
Loop
rsEL.MoveFirst
rs2.Close
Set rs2 = Nothing
End If
rsEL.Close
Set rsEL = Nothing
End If
End If
End If
rs.Close
Set rs = Nothing
wrkDefault.CommitTrans
'
' End of Transaction
'
On Error GoTo 0
If boolWholeChange Then
Set frm = Me.Parent
BuildParticipantListBkGeneric lngTemplateBookingId, "GRID", True
'Rebuild tmpParticipantList so that the list box will show the new
participant
frm!lstParticipants.Requery 'refresh the list
box
frm!lstParticipantsMulti.Requery 'refresh the list
box
HighLightSelectedParticipant frm, frm!ParticipantID
Me.Parent!lstParticipants.SetFocus
DoMaintainParticipantVisibility Me.Parent
frm![CompSelectSubCtl].Visible = True
frm![ElementSelectSubCtl].Visible = True
frm![CompSelectSubCtl].SetFocus
End If
RecalcNumberEnrolled (lngTemplateBookingId)
Exit Sub
'
' Transaction error trap
'
CompSelectErr:
wrkDefault.Rollback
strError = Err.Description
On Error GoTo 0
MsgBox strError & vbCrLf & "While attempting to select / unselect
Competencies" & vbCrLf & _
"Changes completely rolled back"
Exit Sub
End Sub