这是我写的处理事务的过程,分享一下吧
Public Function Exsql(ParamArray sql()) As Boolean
'事务执行1个sql语句
Dim cnConn As ADODB.Connection
dim CN as string
Set cnConn = New ADODB.Connection
Dim mysql
On Error GoTo err1
cn="连接字符串"
cnConn.Open CN
cnConn.BeginTrans '开始一个事务
For Each mysql In sql
cnConn.Execute mysql
Next
cnConn.CommitTrans '提交一个事物
Set cnConn = Nothing
Exsql = True
Exit Function
err1:
cnConn.RollbackTrans '回滚一个事物
Exsql = False
End Function
'Begin
On Error GoTo ErrHandler:
Dim objRs1 As New ADODB.Recordset
Dim objRs2 As New ADODB.Recordset
Dim strSQL As String
Dim strMsg As String
strSQL = "SELECT * FROM Shippers WHERE ShipperID = 2"’SQL查询
objRs1.CursorLocation = adUseClient’设置客户端游标
objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText’执行查询生成objrs1记录集
objRs1("Phone") = "(111) 555-1111"’更改表中一条记录phone字段的值
objRs2.Open strSQL, strConn, adOpenKeyset, adLockOptimistic, adCmdText’执行查询生成objrs2记录集
objRs2("Phone") = "(999) 555-9999" ’更改表中记录phone字段的值
objRs2.Update
objRs2.Close
Set objRs2 = Nothing
On Error Resume Next
objRs1.UpdateBatch
If objRs1.ActiveConnection.Errors.Count <> 0 Then
Dim intConflicts As Integer
intConflicts = 0
objRs1.Filter = adFilterConflictingRecords
intConflicts = objRs1.RecordCount
objRs1.Resync adAffectGroup, adResyncUnderlyingValues
If intConflicts > 0 Then
strMsg = "A conflict occurred with updates for " & intConflicts & "records." & vbCrLf & "The values will be restored" " to their original values."
objRs1.MoveFirst
While Not objRs1.EOF
strMsg = strMsg & "SHIPPER = " & objRs1("CompanyName") & vbCrLf
strMsg = strMsg & "Value = " & objRs1("Phone").Value & vbCrLf
strMsg = strMsg & "UnderlyingValue = " & _
objRs1("Phone").UnderlyingValue & vbCrLf
strMsg = strMsg & "OriginalValue = " & _
objRs1("Phone").OriginalValue & vbCrLf
strMsg = strMsg & vbCrLf & "Original value has been restored."
MsgBox strMsg, vbOKOnly, _
"Conflict " & objRs1.AbsolutePosition & _
" of " & intConflicts
objRs1("Phone").Value = objRs1("Phone").OriginalValue
objRs1.MoveNext
Wend
objRs1.UpdateBatch adAffectGroup
Else
strMsg = "Errors occurred during the update. " & _
objRs1.ActiveConnection.Errors(0).Number & " " & _
objRs1.ActiveConnection.Errors(0).Description
End If
On Error GoTo 0
End If
objRs1.MoveFirst
objRs1.Close
Set objRs1 = Nothing
Exit Sub
ErrHandler:
If Not objRs1 Is Nothing Then
If objRs1.State = adStateOpen Then objRs1.Close
Set objRs1 = Nothing
End If
If Not objRs2 Is Nothing Then
If objRs2.State = adStateOpen Then objRs2.Close
Set objRs2 = Nothing
End If
If Err <> 0 Then
MsgBox Err.Source & "-->" & Err.Description, , "Error"
End If
'End
还可以使用当前 Record 的或特定 Field 的 Status 属性来确定已发生的冲突种类。
处理多用户并发访问的方法是加锁。锁是防止其他事务访问指定的资源控制、实现并发控制的一种主要手段。当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。为了控制锁定的资源,应该首先了解系统的空间管理。在SQL Server 2000系统中,最小的空间管理单位是页,一个页有8K。所有的数据、日志、索引都存放在页上。另外,使用页有一个限制,这就是表中的一行数据必须在同一个页上,不能跨页。页上面的空间管理单位是盘区,一个盘区是8个连续的页。表和索引的最小占用单位是盘区。数据库是由一个或者多个表或者索引组成,即是由多个盘区组成。放在一个表上的锁限制对整个表的并发访问;放在盘区上的锁限制了对整个盘区的访问;放在数据页上的锁限制了对整个数据页的访问;放在行上的锁只限制对该行的并发访问。