SQLite Transactions With Visual Basic
SQLite Transactions With Visual Basic
A transaction is an atomic unit of database operations against the data in one or more databases. The effects of all the SQL
statements in a transaction can be either all committed to the database or all rolled back.
In SQLite, any command other than the SELECT will start an implicit transaction. Also, within a transaction a command like
CREATE TABLE ..., VACUUM, PRAGMA, will commit previous changes before executing.
Manual transactions are started with the BEGIN TRANSACTION statement and finished with the COMMIT or ROLLBACK statements.
SQLite supports three non-standard transaction levels: DEFERRED, IMMEDIATE, and EXCLUSIVE. SQLite automatically puts each
command into its own transaction unless we start our own transaction. Note that this may be influenced by the driver too.
SQLite Python driver has the autocommit mode turned off by default and the first SQL command starts a new transaction.
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
con.Open()
End Using
con.Close()
End Using
End Sub
End Module
We create a Friends table and fill it with data. We do not explicitly start a transaction, nor we call commit or rollback
methods. Yet the data is written to the table. It is because by default, we work in the autocommit mode. In this mode each
SQL statement is immediately effective.
cmd.CommandText = "DROP TABLE IF EXISTS Friends"
cmd.ExecuteNonQuery()
cmd.CommandText = "CREATE TABLE Friends(Id INTEGER PRIMARY KEY," _
& "Name TEXT)"
cmd.ExecuteNonQuery()
We drop the Friends table if it already exists. Then we create the table with the CREATE TABLE statement.
1|Tom
2|Rebecca
3|Jim
4|Robert
5|Julian
In the second example we will start a custom transaction with the BeginTransaction() method.
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
con.Open()
Using tr
cmd.Transaction = tr
cmd.CommandText = "DROP TABLE IF EXISTS Friends"
cmd.ExecuteNonQuery()
cmd.CommandText = "CREATE TABLE Friends(Id INTEGER PRIMARY KEY," _
& "Name TEXT)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Tom')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Rebecca')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Jim')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Robert')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Julian')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Jane')"
cmd.ExecuteNonQuery()
End Using
tr.Commit()
End Using
con.Close()
End Using
End Sub
End Module
All SQL commands form a unit. Either all are saved or nothing is saved. This is the basic idea behind transactions.
cmd.Transaction = tr
tr.Commit()
If everything ran OK, we commit the whole transaction to the database. In case of an exception, the transaction is rolled
back behind the scenes.
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
Try
con = New SqliteConnection(cs)
con.Open()
tr = con.BeginTransaction()
cmd = con.CreateCommand()
cmd.Transaction = tr
cmd.CommandText = "DROP TABLE IF EXISTS Friends"
cmd.ExecuteNonQuery()
cmd.CommandText = "CREATE TABLE Friends(Id INTEGER PRIMARY KEY," _
& "Name TEXT)"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Tom')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Rebecca')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Jim')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Robert')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Julian')"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO Friends(Name) VALUES ('Jane')"
cmd.ExecuteNonQuery()
tr.Commit()
Catch ex As SqliteException
Console.WriteLine("Error: {0}", ex.ToString())
If tr IsNot Nothing
Try
tr.Rollback()
Catch ex2 As SqliteException
Console.WriteLine("Transaction rollback failed.")
Console.WriteLine("Error: {0}", ex2.ToString())
Finally
tr.Dispose()
End Try
End If
Finally
If cmd IsNot Nothing
cmd.Dispose()
End If
If tr IsNot Nothing
tr.Dispose()
End If
End Sub
End Module
We create our own Try, Catch, Finally blocks, where we deal with possible issues.
Catch ex As SqliteException
If tr IsNot Nothing
Try
tr.Rollback()
Catch ex2 As SqliteException
Console.WriteLine("Transaction rollback failed.")
Console.WriteLine("Error: {0}", ex2.ToString())
Finally
tr.Dispose()
End Try
End If
When an exception is thrown during the creation of the Friends table, we call the Rollback() method. Rolling back a
transaction might fail too; we check this scenario.
If tr IsNot Nothing
tr.Dispose()
End If
When closing a connection, we might receive another exception. We handle this case here.
Errors
When there is an error in the transaction, the transaction is rolled back an no changes are committed to the database.
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
con.Open()
Using tr
cmd.Transaction = tr
cmd.CommandText = "UPDATE Friends SET Name='Thomas' WHERE Id=1"
cmd.ExecuteNonQuery()
tr.Commit()
End Using
End Using
con.Close()
End Using
End Sub
End Module
In the code example we want to change two names. There are two statements which form a transaction. There is an error in
the second SQL statement. Therefore the transaction is rolled back.
The name of the table is incorrect. There is no Friend table in the database.
$ mono error.exe
...
Running the example will display this error message. The transaction is rolled back.
sqlite> SELECT * FROM Friends;
1|Tom
2|Rebecca
3|Jim
4|Robert
5|Julian
6|Jane
No changes took place in the Friends table. Even if the first UPDATE statement was correct.
We will again try to change two rows; this time without using the SqliteTransaction.
Option Strict On
Imports Mono.Data.Sqlite
Module Example
Sub Main()
con.Open()
End Using
con.Close()
End Using
End Sub
End Module
We try to update two names in the Friends table, Tom to Thomas and Robert to Bob.
$ mono error2.exe
...
1|Thomas
2|Rebecca
3|Jim
4|Robert
5|Julian
6|Jane
However this time, the first UPDATE statement was saved. The second one was not.
In this part of the SQLite Visual Basic tutorial, we have worked with transactions.