/
LocalTransactionScope.vb
154 lines (118 loc) · 5.02 KB
/
LocalTransactionScope.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
' ___________________________________________________
'
' © Hi-Integrity Systems 2012. All rights reserved.
' www.hisystems.com.au - Toby Wicks
' ___________________________________________________
'
Option Strict On
Option Explicit On
Imports DatabaseObjects
Imports System.Data
''' <summary>
''' Represents a local (not distributed) database transaction.
''' Should be used with a 'Using' statement to ensure that the transaction is rolled back if any exception occurs (database or code related).
''' Performs like the System.Transactions.TransactionScope object, except that it only targets local database transactions
''' (i.e. BEING/COMMIT/ROLLBACK TRANSACTION commands) and does not utilise the Microsoft Distributed Transaction Coordinator.
''' </summary>
''' <example>
''' Using localTransaction = New LocalTransactionScope(database)
'''
''' With collection.Add
''' .Field = "Value"
''' .Save()
''' End With
'''
''' localTransaction.Complete()
''' End Using
''' </example>
Public Class LocalTransactionScope
Implements IDisposable
Private _transaction As Database.TransactionsClass
Private _disposed As Boolean
Private _completed As Boolean = False
''' <summary>
''' Begins a local database transaction.
''' </summary>
Public Sub New(database As Database)
Me.New(database, IsolationLevel.Unspecified)
End Sub
''' <summary>
''' Begins a local database transaction.
''' </summary>
Public Sub New(database As Database, isolationLevel As Data.IsolationLevel)
If database Is Nothing Then
Throw New ArgumentNullException
End If
_transaction = database.Transactions
_transaction.Begin(isolationLevel)
End Sub
''' --------------------------------------------------------------------------------
''' <summary>
''' Executes the SQL statement.
''' Returns Nothing/null if no record was selected, otherwise the first field from the
''' returned result.
''' </summary>
''' --------------------------------------------------------------------------------
Public Function ExecuteScalar(ByVal sqlStatement As SQL.ISQLStatement) As Object
Return _transaction.Execute(sqlStatement)
End Function
''' --------------------------------------------------------------------------------
''' <summary>
''' Executes the SQL statement and returns the result.
''' The returned reader can only be used until the LocalTransactionScope is disposed
''' (typically at the end of a using construct).
''' </summary>
''' --------------------------------------------------------------------------------
Public Function Execute(ByVal sqlStatement As SQL.ISQLStatement) As IDataReader
Return _transaction.Execute(sqlStatement)
End Function
''' --------------------------------------------------------------------------------
''' <summary>
''' Executes the SQL statements and returns the first result.
''' The returned reader(s) can only be used until the LocalTransactionScope is disposed
''' (typically at the end of a using construct).
''' </summary>
''' --------------------------------------------------------------------------------
Public Function Execute(ByVal sqlStatements As SQL.ISQLStatement()) As IDataReader
Return _transaction.Execute(sqlStatements)
End Function
''' --------------------------------------------------------------------------------
''' <summary>
''' Executes the SQL statement and returns the number of rows affected.
''' </summary>
''' --------------------------------------------------------------------------------
Public Function ExecuteNonQuery(ByVal sqlStatement As SQL.ISQLStatement) As Integer
Return _transaction.ExecuteNonQuery(sqlStatement)
End Function
''' --------------------------------------------------------------------------------
''' <summary>
''' Executes the SQL statements and returns the number of rows affected for all of the statements.
''' </summary>
''' --------------------------------------------------------------------------------
Public Function ExecuteNonQuery(ByVal sqlStatements As SQL.ISQLStatement()) As Integer
Return _transaction.ExecuteNonQuery(sqlStatements)
End Function
''' <summary>
''' Indicates that the transaction should be commited.
''' </summary>
''' <remarks></remarks>
Public Sub Complete()
If _completed Then
Throw New InvalidOperationException("Transaction has already been completed")
End If
_transaction.Commit()
_completed = True
End Sub
''' <summary>
''' Closes the connection if it has not already been closed / disposed.
''' </summary>
''' <remarks></remarks>
Public Sub Dispose() Implements IDisposable.Dispose
If Not Me._disposed AndAlso Not _completed Then
_transaction.Rollback()
Me._disposed = True
End If
GC.SuppressFinalize(Me)
End Sub
End Class