2 // Mono.Data.Sqlite.SQLiteTransaction.cs
5 // Robert Simpson (robert@blackcastlesoft.com)
7 // Adapted and modified for the Mono Project by
8 // Marek Habersack (grendello@gmail.com)
11 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
12 // Copyright (C) 2007 Marek Habersack
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 /********************************************************
35 * ADO.NET 2.0 Data Provider for Sqlite Version 3.X
36 * Written by Robert Simpson (robert@blackcastlesoft.com)
38 * Released to the public domain, use at your own risk!
39 ********************************************************/
41 namespace Mono.Data.Sqlite
45 using System.Data.Common;
48 /// Sqlite implementation of DbTransaction.
50 public class SqliteTransaction : DbTransaction
53 /// The connection to which this transaction is bound
55 internal SqliteConnection _cnn;
56 internal long _version; // Matches the version of the connection
59 /// Constructs the transaction object, binding it to the supplied connection
61 /// <param name="connection">The connection to open a transaction on</param>
62 /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
63 internal SqliteTransaction(SqliteConnection connection, bool deferredLock)
66 _version = _cnn._version;
68 if (_cnn._transactionLevel++ == 0)
72 using (SqliteCommand cmd = _cnn.CreateCommand())
75 cmd.CommandText = "BEGIN IMMEDIATE";
77 cmd.CommandText = "BEGIN";
79 cmd.ExecuteNonQuery();
82 catch (SqliteException)
84 _cnn._transactionLevel--;
92 /// Commits the current transaction.
94 public override void Commit()
98 if (--_cnn._transactionLevel == 0)
102 using (SqliteCommand cmd = _cnn.CreateCommand())
104 cmd.CommandText = "COMMIT";
105 cmd.ExecuteNonQuery();
120 /// Returns the underlying connection to which this transaction applies.
122 public new SqliteConnection Connection
128 /// Forwards to the local Connection property
130 protected override DbConnection DbConnection
132 get { return Connection; }
136 /// Disposes the transaction. If it is currently active, any changes are rolled back.
138 protected override void Dispose(bool disposing)
145 base.Dispose(disposing);
149 /// Gets the isolation level of the transaction. Sqlite only supports Serializable transactions.
151 public override IsolationLevel IsolationLevel
153 get { return IsolationLevel.Serializable; }
157 /// Rolls back the active transaction.
159 public override void Rollback()
165 using (SqliteCommand cmd = _cnn.CreateCommand())
167 cmd.CommandText = "ROLLBACK";
168 cmd.ExecuteNonQuery();
170 _cnn._transactionLevel = 0;
178 internal bool IsValid(bool throwError)
182 if (throwError == true) throw new ArgumentNullException("No connection associated with this transaction");
186 if (_cnn._transactionLevel == 0)
188 if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "No transaction is active on this connection");
191 if (_cnn._version != _version)
193 if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "The connection was closed and re-opened, changes were rolled back");
196 if (_cnn.State != ConnectionState.Open)
198 if (throwError == true) throw new SqliteException((int)SqliteErrorCode.Misuse, "Connection was closed");