001
下载 SQLiteTransaction.cs
002
003
004
005
006
007
008
namespace
Mono.Data.Sqlite
009
{
010
using
System;
011
using
System.Data;
012
using
System.Data.Common;
013
014
/// <summary>
015
/// SQLite implementation of DbTransaction.
016
/// </summary>
017
public
sealed
class
SqliteTransaction : DbTransaction
018
{
019
/// <summary>
020
/// The connection to which this transaction is bound
021
/// </summary>
022
internal
SqliteConnection _cnn;
023
internal
long
_version;
024
private
IsolationLevel _level;
025
026
/// <summary>
027
/// Constructs the transaction object, binding it to the supplied connection
028
/// </summary>
029
/// <param name="connection">The connection to open a transaction on</param>
030
/// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
031
internal
SqliteTransaction(SqliteConnection connection,
bool
deferredLock)
032
{
033
_cnn = connection;
034
_version = _cnn._version;
035
036
_level = (deferredLock ==
true
) ? IsolationLevel.ReadCommitted : IsolationLevel.Serializable;
037
038
if
(_cnn._transactionLevel++ == 0)
039
{
040
try
041
{
042
using
(SqliteCommand cmd = _cnn.CreateCommand())
043
{
044
if
(!deferredLock)
045
cmd.CommandText =
"BEGIN IMMEDIATE"
;
046
else
047
cmd.CommandText =
"BEGIN"
;
048
049
cmd.ExecuteNonQuery();
050
}
051
}
052
catch
(SqliteException)
053
{
054
_cnn._transactionLevel--;
055
_cnn =
null
;
056
throw
;
057
}
058
}
059
}
060
061
/// <summary>
062
/// Commits the current transaction.
063
/// </summary>
064
public
override
void
Commit()
065
{
066
IsValid(
true
);
067
068
if
(_cnn._transactionLevel - 1 == 0)
069
{
070
using
(SqliteCommand cmd = _cnn.CreateCommand())
071
{
072
cmd.CommandText =
"COMMIT"
;
073
cmd.ExecuteNonQuery();
074
}
075
}
076
_cnn._transactionLevel--;
077
_cnn =
null
;
078
}
079
080
/// <summary>
081
/// Returns the underlying connection to which this transaction applies.
082
/// </summary>
083
public
new
SqliteConnection Connection
084
{
085
get
{
return
_cnn; }
086
}
087
088
/// <summary>
089
/// Forwards to the local Connection property
090
/// </summary>
091
protected
override
DbConnection DbConnection
092
{
093
get
{
return
Connection; }
094
}
095
096
/// <summary>
097
/// Disposes the transaction. If it is currently active, any changes are rolled back.
098
/// </summary>
099
protected
override
void
Dispose(
bool
disposing)
100
{
101
if
(disposing)
102
{
103
lock
(
this
)
104
{
105
if
(IsValid(
false
))
106
Rollback();
107
108
_cnn =
null
;
109
}
110
}
111
base
.Dispose(disposing);
112
}
113
114
/// <summary>
115
/// Gets the isolation level of the transaction. SQLite only supports Serializable transactions.
116
/// </summary>
117
public
override
IsolationLevel IsolationLevel
118
{
119
get
{
return
_level; }
120
}
121
122
/// <summary>
123
/// Rolls back the active transaction.
124
/// </summary>
125
public
override
void
Rollback()
126
{
127
IsValid(
true
);
128
129
IssueRollback(_cnn);
130
131
_cnn._transactionLevel = 0;
132
_cnn =
null
;
133
}
134
135
internal
static
void
IssueRollback(SqliteConnection cnn)
136
{
137
using
(SqliteCommand cmd = cnn.CreateCommand())
138
{
139
cmd.CommandText =
"ROLLBACK"
;
140
cmd.ExecuteNonQuery();
141
}
142
}
143
144
internal
bool
IsValid(
bool
throwError)
145
{
146
if
(_cnn ==
null
)
147
{
148
if
(throwError ==
true
)
throw
new
ArgumentNullException(
"No connection associated with this transaction"
);
149
else
return
false
;
150
}
151
152
if
(_cnn._transactionLevel == 0)
153
{
154
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"No transaction is active on this connection"
);
155
else
return
false
;
156
}
157
if
(_cnn._version != _version)
158
{
159
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"The connection was closed and re-opened, changes were rolled back"
);
160
else
return
false
;
161
}
162
if
(_cnn.State != ConnectionState.Open)
163
{
164
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"Connection was closed"
);
165
else
return
false
;
166
}
167
168
return
true
;
169
}
170
}
171
}
001
002
003
004
005
006
007
008
namespace
Mono.Data.Sqlite
009
{
010
using
System;
011
using
System.Data;
012
using
System.Data.Common;
013
014
/// <summary>
015
/// SQLite implementation of DbTransaction.
016
/// </summary>
017
public
sealed
class
SqliteTransaction : DbTransaction
018
{
019
/// <summary>
020
/// The connection to which this transaction is bound
021
/// </summary>
022
internal
SqliteConnection _cnn;
023
internal
long
_version;
024
private
IsolationLevel _level;
025
026
/// <summary>
027
/// Constructs the transaction object, binding it to the supplied connection
028
/// </summary>
029
/// <param name="connection">The connection to open a transaction on</param>
030
/// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
031
internal
SqliteTransaction(SqliteConnection connection,
bool
deferredLock)
032
{
033
_cnn = connection;
034
_version = _cnn._version;
035
036
_level = (deferredLock ==
true
) ? IsolationLevel.ReadCommitted : IsolationLevel.Serializable;
037
038
if
(_cnn._transactionLevel++ == 0)
039
{
040
try
041
{
042
using
(SqliteCommand cmd = _cnn.CreateCommand())
043
{
044
if
(!deferredLock)
045
cmd.CommandText =
"BEGIN IMMEDIATE"
;
046
else
047
cmd.CommandText =
"BEGIN"
;
048
049
cmd.ExecuteNonQuery();
050
}
051
}
052
catch
(SqliteException)
053
{
054
_cnn._transactionLevel--;
055
_cnn =
null
;
056
throw
;
057
}
058
}
059
}
060
061
/// <summary>
062
/// Commits the current transaction.
063
/// </summary>
064
public
override
void
Commit()
065
{
066
IsValid(
true
);
067
068
if
(_cnn._transactionLevel - 1 == 0)
069
{
070
using
(SqliteCommand cmd = _cnn.CreateCommand())
071
{
072
cmd.CommandText =
"COMMIT"
;
073
cmd.ExecuteNonQuery();
074
}
075
}
076
_cnn._transactionLevel--;
077
_cnn =
null
;
078
}
079
080
/// <summary>
081
/// Returns the underlying connection to which this transaction applies.
082
/// </summary>
083
public
new
SqliteConnection Connection
084
{
085
get
{
return
_cnn; }
086
}
087
088
/// <summary>
089
/// Forwards to the local Connection property
090
/// </summary>
091
protected
override
DbConnection DbConnection
092
{
093
get
{
return
Connection; }
094
}
095
096
/// <summary>
097
/// Disposes the transaction. If it is currently active, any changes are rolled back.
098
/// </summary>
099
protected
override
void
Dispose(
bool
disposing)
100
{
101
if
(disposing)
102
{
103
lock
(
this
)
104
{
105
if
(IsValid(
false
))
106
Rollback();
107
108
_cnn =
null
;
109
}
110
}
111
base
.Dispose(disposing);
112
}
113
114
/// <summary>
115
/// Gets the isolation level of the transaction. SQLite only supports Serializable transactions.
116
/// </summary>
117
public
override
IsolationLevel IsolationLevel
118
{
119
get
{
return
_level; }
120
}
121
122
/// <summary>
123
/// Rolls back the active transaction.
124
/// </summary>
125
public
override
void
Rollback()
126
{
127
IsValid(
true
);
128
129
IssueRollback(_cnn);
130
131
_cnn._transactionLevel = 0;
132
_cnn =
null
;
133
}
134
135
internal
static
void
IssueRollback(SqliteConnection cnn)
136
{
137
using
(SqliteCommand cmd = cnn.CreateCommand())
138
{
139
cmd.CommandText =
"ROLLBACK"
;
140
cmd.ExecuteNonQuery();
141
}
142
}
143
144
internal
bool
IsValid(
bool
throwError)
145
{
146
if
(_cnn ==
null
)
147
{
148
if
(throwError ==
true
)
throw
new
ArgumentNullException(
"No connection associated with this transaction"
);
149
else
return
false
;
150
}
151
152
if
(_cnn._transactionLevel == 0)
153
{
154
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"No transaction is active on this connection"
);
155
else
return
false
;
156
}
157
if
(_cnn._version != _version)
158
{
159
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"The connection was closed and re-opened, changes were rolled back"
);
160
else
return
false
;
161
}
162
if
(_cnn.State != ConnectionState.Open)
163
{
164
if
(throwError ==
true
)
throw
new
SqliteException((
int
)SQLiteErrorCode.Misuse,
"Connection was closed"
);
165
else
return
false
;
166
}
167
168
return
true
;
169
}
170
}
171
}