From b34b4623eddd05e91b8413ddc19036fb9e6e5855 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Mon, 31 Oct 2016 08:47:11 -0200
Subject: [PATCH] Replace transaction.setComplete() by
 database.commitTransaction()

---
 .../ForumSharingIntegrationTest.java          |   8 +-
 .../briarproject/PrivateGroupManagerTest.java |   8 +-
 .../IntroductionIntegrationTest.java          |  18 +--
 .../api/db/DatabaseComponent.java             |  14 +-
 .../org/briarproject/api/db/Transaction.java  |  18 +--
 .../briarproject/blogs/BlogManagerImpl.java   |  16 +--
 .../clients/BdfIncomingMessageHook.java       |   4 +-
 .../clients/ClientHelperImpl.java             |  16 +--
 .../contact/ContactExchangeTaskImpl.java      |   2 +-
 .../contact/ContactManagerImpl.java           |  10 +-
 .../db/DatabaseComponentImpl.java             |  17 ++-
 .../briarproject/feed/FeedManagerImpl.java    |  10 +-
 .../briarproject/forum/ForumManagerImpl.java  |  12 +-
 .../identity/IdentityManagerImpl.java         |   4 +-
 .../introduction/IntroductionManagerImpl.java |   8 +-
 .../lifecycle/LifecycleManagerImpl.java       |   2 +-
 .../messaging/ConversationManagerImpl.java    |   4 +-
 .../messaging/MessagingManagerImpl.java       |   6 +-
 .../privategroup/PrivateGroupManagerImpl.java |  16 +--
 .../TransportPropertyManagerImpl.java         |   8 +-
 .../settings/SettingsManagerImpl.java         |   4 +-
 .../sharing/SharingManagerImpl.java           |  16 +--
 .../sync/DuplexOutgoingSession.java           |   8 +-
 .../briarproject/sync/IncomingSession.java    |   8 +-
 .../sync/SimplexOutgoingSession.java          |   4 +-
 .../sync/ValidationManagerImpl.java           |  18 +--
 .../transport/KeyManagerImpl.java             |   6 +-
 .../transport/TransportKeyManager.java        |   2 +-
 .../blogs/BlogManagerImplTest.java            |  10 +-
 .../clients/ClientHelperImplTest.java         |   8 ++
 .../contact/ContactManagerImplTest.java       |   5 +
 .../db/DatabaseComponentImplTest.java         |  38 ++---
 .../introduction/IntroduceeManagerTest.java   |   9 +-
 .../introduction/IntroducerManagerTest.java   |   3 +-
 .../IntroductionManagerImplTest.java          |  13 +-
 .../introduction/MessageSenderTest.java       |   4 +-
 .../sync/SimplexOutgoingSessionTest.java      |   6 +
 .../sync/ValidationManagerImplTest.java       | 134 ++++++++----------
 .../transport/TransportKeyManagerTest.java    |   3 +-
 39 files changed, 259 insertions(+), 241 deletions(-)

diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
index ccf25040a1..6cc770b158 100644
--- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java
@@ -509,7 +509,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 			Transaction txn = db.startTransaction(false);
 			try {
 				queue.sendMessage(txn, group, time, body, new Metadata());
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -580,7 +580,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 			DatabaseComponent db1 = t1.getDatabaseComponent();
 			Transaction txn = db1.startTransaction(false);
 			db1.addGroup(txn, forum0.getGroup());
-			txn.setComplete();
+			db1.commitTransaction(txn);
 			db1.endTransaction(txn);
 
 			// send invitation
@@ -707,7 +707,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 			Transaction txn = db.startTransaction(false);
 			try {
 				queue.sendMessage(txn, group, time, body, new Metadata());
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -736,7 +736,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
 			DatabaseComponent db2 = t2.getDatabaseComponent();
 			Transaction txn = db2.startTransaction(false);
 			db2.addGroup(txn, forum0.getGroup());
-			txn.setComplete();
+			db2.commitTransaction(txn);
 			db2.endTransaction(txn);
 
 			// add listeners
diff --git a/briar-android-tests/src/test/java/org/briarproject/PrivateGroupManagerTest.java b/briar-android-tests/src/test/java/org/briarproject/PrivateGroupManagerTest.java
index 409d4af7fe..75d8791084 100644
--- a/briar-android-tests/src/test/java/org/briarproject/PrivateGroupManagerTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/PrivateGroupManagerTest.java
@@ -339,7 +339,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
 		t0.getDatabaseComponent()
 				.setVisibleToContact(txn0, contactId1, privateGroup0.getId(),
 						true);
-		txn0.setComplete();
+		t0.getDatabaseComponent().commitTransaction(txn0);
 		t0.getDatabaseComponent().endTransaction(txn0);
 
 		// author1 joins privateGroup0 and refers to wrong NEW_MEMBER message
@@ -358,7 +358,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
 		t1.getDatabaseComponent()
 				.setVisibleToContact(txn1, contactId0, privateGroup0.getId(),
 						true);
-		txn1.setComplete();
+		t1.getDatabaseComponent().commitTransaction(txn1);
 		t1.getDatabaseComponent().endTransaction(txn1);
 
 		// sync join messages
@@ -467,7 +467,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
 		t0.getDatabaseComponent()
 				.setVisibleToContact(txn0, contactId1, privateGroup0.getId(),
 						true);
-		txn0.setComplete();
+		t0.getDatabaseComponent().commitTransaction(txn0);;
 		t0.getDatabaseComponent().endTransaction(txn0);
 
 		// author1 joins privateGroup0
@@ -487,7 +487,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
 		t1.getDatabaseComponent()
 				.setVisibleToContact(txn1, contactId0, privateGroup0.getId(),
 						true);
-		txn1.setComplete();
+		t1.getDatabaseComponent().commitTransaction(txn1);
 		t1.getDatabaseComponent().endTransaction(txn1);
 
 		// sync join messages
diff --git a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java
index 961b6ad666..90beb65957 100644
--- a/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/introduction/IntroductionIntegrationTest.java
@@ -590,7 +590,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			Transaction txn = db0.startTransaction(false);
 			try {
 				sender0.sendMessage(txn, d);
-				txn.setComplete();
+				db0.commitTransaction(txn);
 			} finally {
 				db0.endTransaction(txn);
 			}
@@ -637,7 +637,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			Transaction txn = db1.startTransaction(false);
 			try {
 				map = db1.getMessageMetadata(txn, group1.getId());
-				txn.setComplete();
+				db1.commitTransaction(txn);
 			} finally {
 				db1.endTransaction(txn);
 			}
@@ -651,7 +651,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			txn = db1.startTransaction(false);
 			try {
 				map = db1.getMessageMetadata(txn, group1.getId());
-				txn.setComplete();
+				db1.commitTransaction(txn);
 			} finally {
 				db1.endTransaction(txn);
 			}
@@ -694,7 +694,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			Transaction txn = db0.startTransaction(false);
 			try {
 				map = db0.getMessageMetadata(txn, group1.getId());
-				txn.setComplete();
+				db0.commitTransaction(txn);
 			} finally {
 				db0.endTransaction(txn);
 			}
@@ -708,7 +708,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			txn = db0.startTransaction(false);
 			try {
 				map = db0.getMessageMetadata(txn, group1.getId());
-				txn.setComplete();
+				db0.commitTransaction(txn);
 			} finally {
 				db0.endTransaction(txn);
 			}
@@ -722,7 +722,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			txn = db0.startTransaction(false);
 			try {
 				map = db0.getMessageMetadata(txn, group1.getId());
-				txn.setComplete();
+				db0.commitTransaction(txn);
 			} finally {
 				db0.endTransaction(txn);
 			}
@@ -780,7 +780,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			try {
 				db0.deleteMessage(txn, responseId);
 				sender0.sendMessage(txn, response);
-				txn.setComplete();
+				db0.commitTransaction(txn);
 			} finally {
 				db0.endTransaction(txn);
 			}
@@ -804,7 +804,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 			txn = db2.startTransaction(true);
 			try {
 				contacts2 = db2.getContacts(txn);
-				txn.setComplete();
+				db2.commitTransaction(txn);
 			} finally {
 				db2.endTransaction(txn);
 			}
@@ -832,7 +832,7 @@ public class IntroductionIntegrationTest extends BriarIntegrationTest {
 				txn = db1.startTransaction(true);
 				try {
 					contacts1 = db1.getContacts(txn);
-					txn.setComplete();
+					db1.commitTransaction(txn);
 				} finally {
 					db1.endTransaction(txn);
 				}
diff --git a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
index cd15469512..b428e096bb 100644
--- a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
+++ b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
@@ -52,11 +52,17 @@ public interface DatabaseComponent {
 	Transaction startTransaction(boolean readOnly) throws DbException;
 
 	/**
-	 * Ends a transaction. If the transaction is marked as complete, the
-	 * transaction is committed and any events attached to the transaction are
-	 * broadcast; otherwise the transaction is aborted.
+	 * Commits a transaction to the database.
 	 */
-	void endTransaction(Transaction txn) throws DbException;
+	void commitTransaction(Transaction txn) throws DbException;
+
+	/**
+	 * Ends a transaction. If the transaction has not been committed,
+	 * it will be aborted. If the transaction has been committed,
+	 * any events attached to the transaction are broadcast.
+	 * The database lock will be released in either case.
+	 */
+	void endTransaction(Transaction txn);
 
 	/**
 	 * Stores a contact associated with the given local and remote pseudonyms,
diff --git a/briar-api/src/org/briarproject/api/db/Transaction.java b/briar-api/src/org/briarproject/api/db/Transaction.java
index 15297a5734..9d6d473c9d 100644
--- a/briar-api/src/org/briarproject/api/db/Transaction.java
+++ b/briar-api/src/org/briarproject/api/db/Transaction.java
@@ -15,7 +15,7 @@ public class Transaction {
 	private final boolean readOnly;
 
 	private List<Event> events = null;
-	private boolean complete = false;
+	private boolean committed = false;
 
 	public Transaction(Object txn, boolean readOnly) {
 		this.txn = txn;
@@ -55,18 +55,18 @@ public class Transaction {
 	}
 
 	/**
-	 * Returns true if the transaction is ready to be committed.
+	 * Returns true if the transaction has been committed.
 	 */
-	public boolean isComplete() {
-		return complete;
+	public boolean isCommitted() {
+		return committed;
 	}
 
 	/**
-	 * Marks the transaction as ready to be committed. This method must not be
-	 * called more than once.
+	 * Marks the transaction as committed. This method should only be called
+	 * by the DatabaseComponent. It must not be called more than once.
 	 */
-	public void setComplete() {
-		if (complete) throw new IllegalStateException();
-		complete = true;
+	public void setCommitted() {
+		if (committed) throw new IllegalStateException();
+		committed = true;
 	}
 }
diff --git a/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java b/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java
index dfb8066b95..ce34fd58fa 100644
--- a/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java
+++ b/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java
@@ -199,7 +199,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 		Transaction txn = db.startTransaction(true);
 		try {
 			boolean canBeRemoved = canBeRemoved(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return canBeRemoved;
 		} finally {
 			db.endTransaction(txn);
@@ -228,7 +228,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 			for (RemoveBlogHook hook : removeHooks)
 				hook.removingBlog(txn, b);
 			db.removeGroup(txn, b.getGroup());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -239,7 +239,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 		Transaction txn = db.startTransaction(false);
 		try {
 			addLocalPost(txn, p);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			//noinspection ThrowFromFinallyBlock
 			db.endTransaction(txn);
@@ -309,7 +309,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 							meta);
 			BlogPostAddedEvent event = new BlogPostAddedEvent(groupId, h, true);
 			txn.attach(event);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} catch (GeneralSecurityException e) {
@@ -394,7 +394,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 		Transaction txn = db.startTransaction(true);
 		try {
 			blog = getBlog(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -441,7 +441,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 				for (Group g : groups) {
 					blogs.add(blogFactory.parseBlog(g));
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -459,7 +459,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 			BdfDictionary meta =
 					clientHelper.getMessageMetadataAsDictionary(txn, m);
 			BlogPostHeader h = getPostHeaderFromMetadata(txn, g, m, meta);
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return h;
 		} catch (FormatException e) {
 			throw new DbException(e);
@@ -538,7 +538,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
 								authorStatuses);
 				headers.add(h);
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return headers;
 		} catch (FormatException e) {
 			throw new DbException(e);
diff --git a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java
index 575a2433d4..394b031bc0 100644
--- a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java
+++ b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java
@@ -95,7 +95,7 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
 		Transaction txn = db.startTransaction(true);
 		try {
 			count = getGroupCount(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		}
 		finally {
 			db.endTransaction(txn);
@@ -157,7 +157,7 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
 						c.getUnreadCount() + (read ? -1 : 1));
 				clientHelper.mergeGroupMetadata(txn, g, d);
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
diff --git a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java
index 9c0354419a..d72d78b550 100644
--- a/briar-core/src/org/briarproject/clients/ClientHelperImpl.java
+++ b/briar-core/src/org/briarproject/clients/ClientHelperImpl.java
@@ -67,7 +67,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(false);
 		try {
 			addLocalMessage(txn, m, metadata, shared);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -99,7 +99,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(true);
 		try {
 			list = getMessageAsList(txn, m);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -122,7 +122,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(true);
 		try {
 			dictionary = getGroupMetadataAsDictionary(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -143,7 +143,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(true);
 		try {
 			dictionary = getMessageMetadataAsDictionary(txn, m);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -164,7 +164,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(true);
 		try {
 			map = getMessageMetadataAsDictionary(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -190,7 +190,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(true);
 		try {
 			map = getMessageMetadataAsDictionary(txn, g, query);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -216,7 +216,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(false);
 		try {
 			mergeGroupMetadata(txn, g, metadata);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -234,7 +234,7 @@ class ClientHelperImpl implements ClientHelper {
 		Transaction txn = db.startTransaction(false);
 		try {
 			mergeMessageMetadata(txn, m, metadata);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java
index eb91ed6bd9..85eb36f9a6 100644
--- a/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java
+++ b/briar-core/src/org/briarproject/contact/ContactExchangeTaskImpl.java
@@ -314,7 +314,7 @@ public class ContactExchangeTaskImpl extends Thread
 					localAuthor.getId(), master, timestamp, alice, true, true);
 			transportPropertyManager.addRemoteProperties(txn, contactId,
 					remoteProperties);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/contact/ContactManagerImpl.java b/briar-core/src/org/briarproject/contact/ContactManagerImpl.java
index 42a0cd5ecc..c0d13a44f8 100644
--- a/briar-core/src/org/briarproject/contact/ContactManagerImpl.java
+++ b/briar-core/src/org/briarproject/contact/ContactManagerImpl.java
@@ -65,7 +65,7 @@ class ContactManagerImpl implements ContactManager {
 		try {
 			c = addContact(txn, remote, local, master, timestamp, alice,
 					verified, active);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -78,7 +78,7 @@ class ContactManagerImpl implements ContactManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			contact = db.getContact(txn, c);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -91,7 +91,7 @@ class ContactManagerImpl implements ContactManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			contacts = db.getContacts(txn);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -105,7 +105,7 @@ class ContactManagerImpl implements ContactManager {
 		Transaction txn = db.startTransaction(false);
 		try {
 			removeContact(txn, c);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -130,7 +130,7 @@ class ContactManagerImpl implements ContactManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			exists = contactExists(txn, remoteAuthorId, localAuthorId);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 3265db024b..36ff8b29db 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -139,21 +139,28 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 	}
 
 	@Override
-	public void endTransaction(Transaction transaction) throws DbException {
+	public void commitTransaction(Transaction transaction) throws DbException {
+		T txn = txnClass.cast(transaction.unbox());
+		if (transaction.isCommitted()) throw new IllegalStateException();
+		transaction.setCommitted();
+		db.commitTransaction(txn);
+	}
+
+	@Override
+	public void endTransaction(Transaction transaction) {
 		try {
 			T txn = txnClass.cast(transaction.unbox());
-			if (transaction.isComplete()) db.commitTransaction(txn);
-			else db.abortTransaction(txn);
+			if (!transaction.isCommitted()) db.abortTransaction(txn);
 		} finally {
 			if (transaction.isReadOnly()) lock.readLock().unlock();
 			else lock.writeLock().unlock();
 		}
-		if (transaction.isComplete())
+		if (transaction.isCommitted())
 			for (Event e : transaction.getEvents()) eventBus.broadcast(e);
 	}
 
 	private T unbox(Transaction transaction) {
-		if (transaction.isComplete()) throw new IllegalStateException();
+		if (transaction.isCommitted()) throw new IllegalStateException();
 		return txnClass.cast(transaction.unbox());
 	}
 
diff --git a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
index 1d9eebea9c..11e98eeacd 100644
--- a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
+++ b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java
@@ -180,7 +180,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
 			List<Feed> feeds = getFeeds(txn);
 			feeds.add(feed);
 			storeFeeds(txn, feeds);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -200,7 +200,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
 			feeds.remove(feed);
 			feeds.add(updatedFeed);
 			storeFeeds(txn, feeds);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -222,7 +222,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
 			}
 			if (!found) throw new DbException();
 			storeFeeds(txn, feeds);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -234,7 +234,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
 		Transaction txn = db.startTransaction(true);
 		try {
 			feeds = getFeeds(txn);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -405,7 +405,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
 					if (entryTime > lastEntryTime) lastEntryTime = entryTime;
 				}
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java
index 44f7659e1d..f173fafc62 100644
--- a/briar-core/src/org/briarproject/forum/ForumManagerImpl.java
+++ b/briar-core/src/org/briarproject/forum/ForumManagerImpl.java
@@ -104,7 +104,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 		Transaction txn = db.startTransaction(false);
 		try {
 			db.addGroup(txn, f.getGroup());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -118,7 +118,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 			for (RemoveForumHook hook : removeHooks)
 				hook.removingForum(txn, f);
 			db.removeGroup(txn, f.getGroup());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -160,7 +160,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 			meta.put(MSG_KEY_READ, true);
 			clientHelper.addLocalMessage(txn, p.getMessage(), meta, true);
 			trackOutgoingMessage(txn, p.getMessage());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new RuntimeException(e);
 		} finally {
@@ -176,7 +176,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			forum = getForum(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -200,7 +200,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 			Transaction txn = db.startTransaction(true);
 			try {
 				groups = db.getGroups(txn, CLIENT_ID);
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -252,7 +252,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
 				headers.add(getForumPostHeader(txn, entry.getKey(), meta,
 						statuses));
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return headers;
 		} catch (FormatException e) {
 			throw new DbException(e);
diff --git a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
index 61316e8470..e01e13c4d2 100644
--- a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
+++ b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java
@@ -38,7 +38,7 @@ class IdentityManagerImpl implements IdentityManager {
 		Transaction txn = db.startTransaction(false);
 		try {
 			db.addLocalAuthor(txn, localAuthor);
-			txn.setComplete();
+			db.commitTransaction(txn);
 			cachedAuthor = localAuthor;
 			LOG.info("Local author registered");
 		} finally {
@@ -53,7 +53,7 @@ class IdentityManagerImpl implements IdentityManager {
 			try {
 				cachedAuthor = loadLocalAuthor(txn);
 				LOG.info("Local author loaded");
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
diff --git a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
index e42ee1e097..95a72aed8e 100644
--- a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
+++ b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java
@@ -305,7 +305,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 			Group g2 = getContactGroup(c2);
 			trackMessage(txn, g1.getId(), timestamp, true);
 			trackMessage(txn, g2.getId(), timestamp, true);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -325,7 +325,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 
 			introduceeManager.acceptIntroduction(txn, state, timestamp);
 			trackMessage(txn, g.getId(), timestamp, true);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -345,7 +345,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 
 			introduceeManager.declineIntroduction(txn, state, timestamp);
 			trackMessage(txn, g.getId(), timestamp, true);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -458,7 +458,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
 					if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 				}
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
diff --git a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
index f2857cad6a..fa66b14fde 100644
--- a/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
+++ b/briar-core/src/org/briarproject/lifecycle/LifecycleManagerImpl.java
@@ -140,7 +140,7 @@ class LifecycleManagerImpl implements LifecycleManager {
 								+ " took " + duration + " ms");
 					}
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
diff --git a/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java b/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java
index 670af288ed..dd90690789 100644
--- a/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java
+++ b/briar-core/src/org/briarproject/messaging/ConversationManagerImpl.java
@@ -46,7 +46,7 @@ class ConversationManagerImpl implements ConversationManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			contact = db.getContact(txn, contactId);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -70,7 +70,7 @@ class ConversationManagerImpl implements ConversationManager {
 				if (count.getLatestMsgTime() > latestTime)
 					latestTime = count.getLatestMsgTime();
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
index cc4c1040fd..bf18252996 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
@@ -122,7 +122,7 @@ class MessagingManagerImpl extends ConversationClientImpl
 			meta.put("read", true);
 			clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
 			trackOutgoingMessage(txn, m.getMessage());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new RuntimeException(e);
 		} finally {
@@ -157,7 +157,7 @@ class MessagingManagerImpl extends ConversationClientImpl
 		Transaction txn = db.startTransaction(true);
 		try {
 			contact = db.getContact(txn, c);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -175,7 +175,7 @@ class MessagingManagerImpl extends ConversationClientImpl
 			g = getContactGroup(db.getContact(txn, c)).getId();
 			metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
 			statuses = db.getMessageStatus(txn, c, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
diff --git a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
index a8a867de19..e96c7edf4c 100644
--- a/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
+++ b/briar-core/src/org/briarproject/privategroup/PrivateGroupManagerImpl.java
@@ -108,7 +108,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 			clientHelper.mergeGroupMetadata(txn, group.getId(), meta);
 			announceNewMember(txn, newMemberMsg);
 			joinPrivateGroup(txn, joinMsg);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
@@ -145,7 +145,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 			}
 			Group group = db.getGroup(txn, g);
 			db.removeGroup(txn, group);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -157,7 +157,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 		Transaction txn = db.startTransaction(true);
 		try {
 			previousMsgId = getPreviousMsgId(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
@@ -216,7 +216,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 			setPreviousMsgId(txn, m.getMessage().getGroupId(),
 					m.getMessage().getId());
 			trackOutgoingMessage(txn, m.getMessage());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
@@ -242,7 +242,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 		Transaction txn = db.startTransaction(true);
 		try {
 			privateGroup = getPrivateGroup(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -266,7 +266,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 		Transaction txn = db.startTransaction(true);
 		try {
 			groups = db.getGroups(txn, getClientId());
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -333,7 +333,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 				headers.add(getGroupMessageHeader(txn, g, entry.getKey(), meta,
 						statuses));
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return headers;
 		} catch (FormatException e) {
 			throw new DbException(e);
@@ -387,7 +387,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
 				}
 				members.add(new GroupMember(a, status, shared));
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return members;
 		} finally {
 			db.endTransaction(txn);
diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
index cdf7d4eabd..cabfe6d056 100644
--- a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
+++ b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
@@ -101,7 +101,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 		Transaction txn = db.startTransaction(true);
 		try {
 			local = getLocalProperties(txn);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -145,7 +145,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 							latest.messageId);
 					p = parseProperties(message);
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -176,7 +176,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 						remote.put(c.getId(), parseProperties(message));
 					}
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -222,7 +222,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
 								true, true);
 					}
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
diff --git a/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java b/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
index 3df277318c..cfd20daf23 100644
--- a/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
+++ b/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
@@ -24,7 +24,7 @@ class SettingsManagerImpl implements SettingsManager {
 		Transaction txn = db.startTransaction(true);
 		try {
 			s = db.getSettings(txn, namespace);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -36,7 +36,7 @@ class SettingsManagerImpl implements SettingsManager {
 		Transaction txn = db.startTransaction(false);
 		try {
 			db.mergeSettings(txn, s, namespace);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
index a355018773..9699f3a34f 100644
--- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
+++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java
@@ -300,7 +300,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 			long time = update.toSend.get(0).getTime();
 			trackMessage(txn, localState.getGroupId(), time, true);
 
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException();
 		} finally {
@@ -317,7 +317,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 			// find session state based on shareable
 			IS localState = getSessionStateForResponse(txn, f, c);
 			respondToInvitation(txn, localState, accept);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
@@ -333,7 +333,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 		try {
 			IS localState = (IS) getSessionState(txn, id, true);
 			respondToInvitation(txn, localState, accept);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		} finally {
@@ -427,7 +427,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 						LOG.log(WARNING, e.toString(), e);
 				}
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return list;
 		} catch (FormatException e) {
 			throw new DbException(e);
@@ -468,7 +468,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 						new SharingInvitationItem(s, subscribed, newS);
 				invitations.add(invitation);
 			}
-			txn.setComplete();
+			db.commitTransaction(txn);
 			return Collections.unmodifiableCollection(invitations);
 		} catch (FormatException e) {
 			throw new DbException(e);
@@ -514,7 +514,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 		Transaction txn = db.startTransaction(true);
 		try {
 			subscribers = getSharedBy(txn, g);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -547,7 +547,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 					if (listContains(txn, contactGroup, g, SHARED_BY_US))
 						shared.add(c);
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -563,7 +563,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
 		Transaction txn = db.startTransaction(true);
 		try {
 			canBeShared = canBeShared(txn, g, c);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/sync/DuplexOutgoingSession.java b/briar-core/src/org/briarproject/sync/DuplexOutgoingSession.java
index 7c87c31514..a4c8f499f2 100644
--- a/briar-core/src/org/briarproject/sync/DuplexOutgoingSession.java
+++ b/briar-core/src/org/briarproject/sync/DuplexOutgoingSession.java
@@ -175,7 +175,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -217,7 +217,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 				try {
 					b = db.generateRequestedBatch(txn, contactId,
 							MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -259,7 +259,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 				try {
 					o = db.generateOffer(txn, contactId, MAX_MESSAGE_IDS,
 							maxLatency);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -300,7 +300,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					r = db.generateRequest(txn, contactId, MAX_MESSAGE_IDS);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
diff --git a/briar-core/src/org/briarproject/sync/IncomingSession.java b/briar-core/src/org/briarproject/sync/IncomingSession.java
index 2a06d29cb0..b434bb6430 100644
--- a/briar-core/src/org/briarproject/sync/IncomingSession.java
+++ b/briar-core/src/org/briarproject/sync/IncomingSession.java
@@ -102,7 +102,7 @@ class IncomingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					db.receiveAck(txn, contactId, ack);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -126,7 +126,7 @@ class IncomingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					db.receiveMessage(txn, contactId, message);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -150,7 +150,7 @@ class IncomingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					db.receiveOffer(txn, contactId, offer);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -174,7 +174,7 @@ class IncomingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					db.receiveRequest(txn, contactId, request);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
diff --git a/briar-core/src/org/briarproject/sync/SimplexOutgoingSession.java b/briar-core/src/org/briarproject/sync/SimplexOutgoingSession.java
index 5623c275e7..a2caf77c5e 100644
--- a/briar-core/src/org/briarproject/sync/SimplexOutgoingSession.java
+++ b/briar-core/src/org/briarproject/sync/SimplexOutgoingSession.java
@@ -117,7 +117,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
 				Transaction txn = db.startTransaction(false);
 				try {
 					a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
@@ -160,7 +160,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
 				try {
 					b = db.generateBatch(txn, contactId,
 							MAX_PACKET_PAYLOAD_LENGTH, maxLatency);
-					txn.setComplete();
+					db.commitTransaction(txn);
 				} finally {
 					db.endTransaction(txn);
 				}
diff --git a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java
index 1bedf751f3..5bebd3009f 100644
--- a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java
+++ b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java
@@ -106,7 +106,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 			Transaction txn = db.startTransaction(true);
 			try {
 				unvalidated.addAll(db.getMessagesToValidate(txn, c));
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -136,7 +136,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 				byte[] raw = db.getRawMessage(txn, id);
 				m = parseMessage(id, raw);
 				g = db.getGroup(txn, m.getGroupId());
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -168,7 +168,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 			Transaction txn = db.startTransaction(true);
 			try {
 				pending.addAll(db.getPendingMessages(txn, c));
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -228,7 +228,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 						}
 					}
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -338,7 +338,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 						db.setMessageState(txn, id, PENDING);
 					}
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -397,7 +397,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 			Transaction txn = db.startTransaction(true);
 			try {
 				toShare.addAll(db.getMessagesToShare(txn, c));
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -430,7 +430,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 				MessageId id = toShare.poll();
 				db.setMessageShared(txn, id);
 				toShare.addAll(db.getMessageDependencies(txn, id).keySet());
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -465,7 +465,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 					invalidateMessage(txn, id);
 					invalidate.addAll(getDependentsToInvalidate(txn, id));
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -520,7 +520,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 			Transaction txn = db.startTransaction(true);
 			try {
 				g = db.getGroup(txn, m.getGroupId());
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
index 03b2c13666..7d75fd3b34 100644
--- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
+++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
@@ -89,7 +89,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 					managers.put(e.getKey(), m);
 					m.start(txn);
 				}
-				txn.setComplete();
+				db.commitTransaction(txn);
 			} finally {
 				db.endTransaction(txn);
 			}
@@ -123,7 +123,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		Transaction txn = db.startTransaction(false);
 		try {
 			ctx = m.getStreamContext(txn, c);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
@@ -142,7 +142,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 		Transaction txn = db.startTransaction(false);
 		try {
 			ctx = m.getStreamContext(txn, tag);
-			txn.setComplete();
+			db.commitTransaction(txn);
 		} finally {
 			db.endTransaction(txn);
 		}
diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManager.java b/briar-core/src/org/briarproject/transport/TransportKeyManager.java
index 1fb37877fc..4210c31ed4 100644
--- a/briar-core/src/org/briarproject/transport/TransportKeyManager.java
+++ b/briar-core/src/org/briarproject/transport/TransportKeyManager.java
@@ -143,7 +143,7 @@ class TransportKeyManager {
 					Transaction txn = db.startTransaction(false);
 					try {
 						rotateKeys(txn);
-						txn.setComplete();
+						db.commitTransaction(txn);
 					} finally {
 						db.endTransaction(txn);
 					}
diff --git a/briar-tests/src/org/briarproject/blogs/BlogManagerImplTest.java b/briar-tests/src/org/briarproject/blogs/BlogManagerImplTest.java
index ac7d27cd13..0e97c4c2f2 100644
--- a/briar-tests/src/org/briarproject/blogs/BlogManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/blogs/BlogManagerImplTest.java
@@ -198,12 +198,12 @@ public class BlogManagerImplTest extends BriarTestCase {
 					blog2.getAuthor().getId());
 			will(returnValue(false));
 			oneOf(db).removeGroup(txn, blog1.getGroup());
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
 		blogManager.removeBlog(blog1);
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 	}
 
 	@Test
@@ -227,12 +227,12 @@ public class BlogManagerImplTest extends BriarTestCase {
 			oneOf(identityManager)
 					.getAuthorStatus(txn, blog1.getAuthor().getId());
 			will(returnValue(VERIFIED));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
 		blogManager.addLocalPost(post);
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 
 		assertEquals(1, txn.getEvents().size());
 		assertTrue(txn.getEvents().get(0) instanceof BlogPostAddedEvent);
@@ -256,11 +256,11 @@ public class BlogManagerImplTest extends BriarTestCase {
 		context.checking(new Expectations() {{
 			oneOf(identityManager).getLocalAuthor(txn);
 			will(returnValue(blog1.getAuthor()));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 		assertFalse(blogManager.canBeRemoved(blog1.getId()));
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 
 		// check that blogs of contacts can not be removed
 		final Transaction txn2 = new Transaction(null, true);
@@ -271,11 +271,11 @@ public class BlogManagerImplTest extends BriarTestCase {
 			oneOf(contactManager).contactExists(txn2, blog1.getAuthor().getId(),
 					blog2.getAuthor().getId());
 			will(returnValue(true));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 		}});
 		assertFalse(blogManager.canBeRemoved(blog1.getId()));
 		context.assertIsSatisfied();
-		assertTrue(txn2.isComplete());
 
 		// check that blogs can be removed if they don't belong to a contact
 		final Transaction txn3 = new Transaction(null, true);
@@ -286,11 +286,11 @@ public class BlogManagerImplTest extends BriarTestCase {
 			oneOf(contactManager).contactExists(txn3, blog1.getAuthor().getId(),
 					blog2.getAuthor().getId());
 			will(returnValue(false));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 		}});
 		assertTrue(blogManager.canBeRemoved(blog1.getId()));
 		context.assertIsSatisfied();
-		assertTrue(txn3.isComplete());
 	}
 
 	private void checkGetBlogExpectations(final Transaction txn,
diff --git a/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java b/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java
index 26aa375a45..73e17616a1 100644
--- a/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java
+++ b/briar-tests/src/org/briarproject/clients/ClientHelperImplTest.java
@@ -89,6 +89,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			oneOf(metadataEncoder).encode(dictionary);
 			will(returnValue(metadata));
 			oneOf(db).addLocalMessage(txn, message, metadata, shared);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -118,6 +119,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getRawMessage(txn, messageId);
 			will(returnValue(rawMessage));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -136,6 +138,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			will(returnValue(metadata));
 			oneOf(metadataParser).parse(metadata);
 			will(returnValue(dictionary));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -155,6 +158,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			will(returnValue(metadata));
 			oneOf(metadataParser).parse(metadata);
 			will(returnValue(dictionary));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -176,6 +180,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			will(returnValue(Collections.singletonMap(messageId, metadata)));
 			oneOf(metadataParser).parse(metadata);
 			will(returnValue(dictionary));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -203,6 +208,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			will(returnValue(Collections.singletonMap(messageId, metadata)));
 			oneOf(metadataParser).parse(metadata);
 			will(returnValue(dictionary));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -221,6 +227,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			oneOf(metadataEncoder).encode(dictionary);
 			will(returnValue(metadata));
 			oneOf(db).mergeGroupMetadata(txn, groupId, metadata);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -238,6 +245,7 @@ public class ClientHelperImplTest extends BriarTestCase {
 			oneOf(metadataEncoder).encode(dictionary);
 			will(returnValue(metadata));
 			oneOf(db).mergeMessageMetadata(txn, messageId, metadata);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
diff --git a/briar-tests/src/org/briarproject/contact/ContactManagerImplTest.java b/briar-tests/src/org/briarproject/contact/ContactManagerImplTest.java
index 862b40d91f..d7ebb8302c 100644
--- a/briar-tests/src/org/briarproject/contact/ContactManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/contact/ContactManagerImplTest.java
@@ -59,6 +59,7 @@ public class ContactManagerImplTest extends BriarTestCase {
 					.addContact(txn, contactId, master, timestamp, alice);
 			oneOf(db).getContact(txn, contactId);
 			will(returnValue(contact));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -76,6 +77,7 @@ public class ContactManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getContact(txn, contactId);
 			will(returnValue(contact));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -94,6 +96,7 @@ public class ContactManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getContacts(txn);
 			will(returnValue(contacts));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -110,6 +113,7 @@ public class ContactManagerImplTest extends BriarTestCase {
 			oneOf(db).getContact(txn, contactId);
 			will(returnValue(contact));
 			oneOf(db).removeContact(txn, contactId);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -136,6 +140,7 @@ public class ContactManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).containsContact(txn, remote.getId(), local);
 			will(returnValue(true));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
diff --git a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
index 0b5016b8d9..f2be5bb18a 100644
--- a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
+++ b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
@@ -211,7 +211,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			db.removeGroup(transaction, group);
 			db.removeContact(transaction, contactId);
 			db.removeLocalAuthor(transaction, localAuthorId);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -284,7 +284,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.addLocalMessage(transaction, message, metadata, true);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -850,7 +850,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			assertEquals(contactId,
 					db.addContact(transaction, author, localAuthorId, true,
 							true));
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -925,7 +925,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			Ack a = db.generateAck(transaction, contactId, 123);
 			assertEquals(messagesToAck, a.getMessageIds());
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -969,7 +969,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			assertEquals(messages, db.generateBatch(transaction, contactId,
 					size * 2, maxLatency));
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1006,7 +1006,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			Offer o = db.generateOffer(transaction, contactId, 123, maxLatency);
 			assertEquals(ids, o.getMessageIds());
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1040,7 +1040,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			Request r = db.generateRequest(transaction, contactId, 123);
 			assertEquals(ids, r.getMessageIds());
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1085,7 +1085,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			assertEquals(messages, db.generateRequestedBatch(transaction,
 					contactId, size * 2, maxLatency));
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1118,7 +1118,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			Ack a = new Ack(Collections.singletonList(messageId));
 			db.receiveAck(transaction, contactId, a);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1173,7 +1173,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			// Receive the message twice
 			db.receiveMessage(transaction, contactId, message);
 			db.receiveMessage(transaction, contactId, message);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1210,7 +1210,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.receiveMessage(transaction, contactId, message);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1240,7 +1240,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.receiveMessage(transaction, contactId, message);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1294,7 +1294,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			Offer o = new Offer(Arrays.asList(messageId, messageId1,
 					messageId2, messageId3));
 			db.receiveOffer(transaction, contactId, o);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1328,7 +1328,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			Request r = new Request(Collections.singletonList(messageId));
 			db.receiveRequest(transaction, contactId, r);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1368,7 +1368,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.setVisibleToContact(transaction, contactId, groupId, true);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1401,7 +1401,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		Transaction transaction = db.startTransaction(false);
 		try {
 			db.setVisibleToContact(transaction, contactId, groupId, true);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1444,7 +1444,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 		try {
 			db.updateTransportKeys(transaction, keys);
 			assertEquals(keys, db.getTransportKeys(transaction, transportId));
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1512,7 +1512,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			db.mergeSettings(transaction, update, "namespace");
 			// Second merge should not broadcast an event
 			db.mergeSettings(transaction, update, "namespace");
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
@@ -1711,7 +1711,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
 			db.addMessageDependencies(transaction, message, dependencies);
 			db.getMessageDependencies(transaction, messageId);
 			db.getMessageDependents(transaction, messageId);
-			transaction.setComplete();
+			db.commitTransaction(transaction);
 		} finally {
 			db.endTransaction(transaction);
 		}
diff --git a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java
index b5c4ff6841..2ac86ea65f 100644
--- a/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java
+++ b/briar-tests/src/org/briarproject/introduction/IntroduceeManagerTest.java
@@ -199,8 +199,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		introduceeManager.incomingMessage(txn, state, msg);
 
 		context.assertIsSatisfied();
-
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 	@Test
@@ -234,8 +233,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		introduceeManager.incomingMessage(txn, state, msg);
 
 		context.assertIsSatisfied();
-
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 	@Test
@@ -297,7 +295,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 			assertTrue(e.getCause() instanceof GeneralSecurityException);
 		}
 		context.assertIsSatisfied();
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 	@Test
@@ -448,6 +446,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
 		BdfDictionary result = introduceeManager.initialize(txn, groupId, msg);
 
 		context.assertIsSatisfied();
+		assertFalse(txn.isCommitted());
 		return result;
 	}
 
diff --git a/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java b/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java
index caa0aeb84f..cf8640edab 100644
--- a/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java
+++ b/briar-tests/src/org/briarproject/introduction/IntroducerManagerTest.java
@@ -179,8 +179,7 @@ public class IntroducerManagerTest extends BriarTestCase {
 				.makeIntroduction(txn, introducee1, introducee2, null, time);
 
 		context.assertIsSatisfied();
-
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 	private ClientId getClientId() {
diff --git a/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java b/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java
index 19903224e5..8bb138be36 100644
--- a/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/introduction/IntroductionManagerImplTest.java
@@ -31,7 +31,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
-import static junit.framework.TestCase.assertTrue;
 import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
 import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1;
 import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2;
@@ -153,6 +152,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 			oneOf(clientHelper)
 					.mergeGroupMetadata(txn, introductionGroup2.getId(),
 							metadataAfter);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -160,7 +160,6 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 				.makeIntroduction(introducee1, introducee2, null, time);
 
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 	}
 
 	@Test
@@ -188,6 +187,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 			oneOf(clientHelper)
 					.mergeGroupMetadata(txn, introductionGroup1.getId(),
 							metadataAfter);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -195,7 +195,6 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 				.acceptIntroduction(introducee1.getId(), sessionId, time);
 
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 	}
 
 	@Test
@@ -223,6 +222,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 			oneOf(clientHelper)
 					.mergeGroupMetadata(txn, introductionGroup1.getId(),
 							metadataAfter);
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
@@ -230,7 +230,6 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 				.declineIntroduction(introducee1.getId(), sessionId, time);
 
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 	}
 
 	@Test
@@ -254,13 +253,13 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 			oneOf(db).getMessageStatus(txn, introducee1.getId(),
 					introductionGroup1.getId());
 			will(returnValue(statuses));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 		}});
 
 		introductionManager.getIntroductionMessages(introducee1.getId());
 
 		context.assertIsSatisfied();
-		assertTrue(txn.isComplete());
 	}
 
 	@Test
@@ -295,7 +294,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 				.incomingMessage(txn, message1, new BdfList(), msg);
 
 		context.assertIsSatisfied();
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 	@Test
@@ -334,7 +333,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
 				.incomingMessage(txn, message1, new BdfList(), msg);
 
 		context.assertIsSatisfied();
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 
diff --git a/briar-tests/src/org/briarproject/introduction/MessageSenderTest.java b/briar-tests/src/org/briarproject/introduction/MessageSenderTest.java
index bbc7cf13d0..bf3fdde3c5 100644
--- a/briar-tests/src/org/briarproject/introduction/MessageSenderTest.java
+++ b/briar-tests/src/org/briarproject/introduction/MessageSenderTest.java
@@ -22,7 +22,6 @@ import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.junit.Test;
 
-import static junit.framework.Assert.assertFalse;
 import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
 import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID;
 import static org.briarproject.api.introduction.IntroductionConstants.MAC;
@@ -30,6 +29,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID
 import static org.briarproject.api.introduction.IntroductionConstants.SIGNATURE;
 import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
 import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
+import static org.junit.Assert.assertFalse;
 
 public class MessageSenderTest extends BriarTestCase {
 
@@ -94,7 +94,7 @@ public class MessageSenderTest extends BriarTestCase {
 		messageSender.sendMessage(txn, msg);
 
 		context.assertIsSatisfied();
-		assertFalse(txn.isComplete());
+		assertFalse(txn.isCommitted());
 	}
 
 }
diff --git a/briar-tests/src/org/briarproject/sync/SimplexOutgoingSessionTest.java b/briar-tests/src/org/briarproject/sync/SimplexOutgoingSessionTest.java
index 57e6eb2fe5..36e9459467 100644
--- a/briar-tests/src/org/briarproject/sync/SimplexOutgoingSessionTest.java
+++ b/briar-tests/src/org/briarproject/sync/SimplexOutgoingSessionTest.java
@@ -57,6 +57,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			will(returnValue(noAckTxn));
 			oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
 			will(returnValue(null));
+			oneOf(db).commitTransaction(noAckTxn);
 			oneOf(db).endTransaction(noAckTxn);
 			// No messages to send
 			oneOf(db).startTransaction(false);
@@ -64,6 +65,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
 					with(any(int.class)), with(maxLatency));
 			will(returnValue(null));
+			oneOf(db).commitTransaction(noMsgTxn);
 			oneOf(db).endTransaction(noMsgTxn);
 			// Flush the output stream
 			oneOf(packetWriter).flush();
@@ -95,6 +97,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			will(returnValue(ackTxn));
 			oneOf(db).generateAck(ackTxn, contactId, MAX_MESSAGE_IDS);
 			will(returnValue(ack));
+			oneOf(db).commitTransaction(ackTxn);
 			oneOf(db).endTransaction(ackTxn);
 			oneOf(packetWriter).writeAck(ack);
 			// One message to send
@@ -103,6 +106,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			oneOf(db).generateBatch(with(msgTxn), with(contactId),
 					with(any(int.class)), with(maxLatency));
 			will(returnValue(Arrays.asList(raw)));
+			oneOf(db).commitTransaction(msgTxn);
 			oneOf(db).endTransaction(msgTxn);
 			oneOf(packetWriter).writeMessage(raw);
 			// No more acks
@@ -110,6 +114,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			will(returnValue(noAckTxn));
 			oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
 			will(returnValue(null));
+			oneOf(db).commitTransaction(noAckTxn);
 			oneOf(db).endTransaction(noAckTxn);
 			// No more messages
 			oneOf(db).startTransaction(false);
@@ -117,6 +122,7 @@ public class SimplexOutgoingSessionTest extends BriarTestCase {
 			oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
 					with(any(int.class)), with(maxLatency));
 			will(returnValue(null));
+			oneOf(db).commitTransaction(noMsgTxn);
 			oneOf(db).endTransaction(noMsgTxn);
 			// Flush the output stream
 			oneOf(packetWriter).flush();
diff --git a/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java b/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java
index 064f5e7496..dea4ab9799 100644
--- a/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/sync/ValidationManagerImplTest.java
@@ -36,8 +36,6 @@ import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
 import static org.briarproject.api.sync.ValidationManager.State.INVALID;
 import static org.briarproject.api.sync.ValidationManager.State.PENDING;
 import static org.briarproject.api.sync.ValidationManager.State.UNKNOWN;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 public class ValidationManagerImplTest extends BriarTestCase {
 
@@ -91,6 +89,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getMessagesToValidate(txn, clientId);
 			will(returnValue(Arrays.asList(messageId, messageId1)));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Load the first raw message and group
 			oneOf(db).startTransaction(true);
@@ -99,6 +98,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(raw));
 			oneOf(db).getGroup(txn1, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Validate the first message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -116,6 +116,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn2, messageId);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Load the second raw message and group
 			oneOf(db).startTransaction(true);
@@ -124,6 +125,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(raw));
 			oneOf(db).getGroup(txn3, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Validate the second message: invalid
 			oneOf(validator).validateMessage(message1, group);
@@ -139,18 +141,21 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Recursively invalidate any dependents
 			oneOf(db).getMessageDependents(txn4, messageId1);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 			// Get pending messages to deliver
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn5));
 			oneOf(db).getPendingMessages(txn5, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn5);
 			oneOf(db).endTransaction(txn5);
 			// Get messages to share
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn6));
 			oneOf(db).getMessagesToShare(txn6, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn6);
 			oneOf(db).endTransaction(txn6);
 		}});
 
@@ -161,14 +166,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.startService();
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
-		assertTrue(txn5.isComplete());
-		assertTrue(txn6.isComplete());
 	}
 
 	@Test
@@ -192,12 +189,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getMessagesToValidate(txn, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Get pending messages to deliver
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn1));
 			oneOf(db).getPendingMessages(txn1, clientId);
 			will(returnValue(Collections.singletonList(messageId)));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Check whether the message is ready to deliver
 			oneOf(db).startTransaction(false);
@@ -222,6 +221,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn2, messageId);
 			will(returnValue(Collections.singletonMap(messageId2, PENDING)));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Check whether the dependent is ready to deliver
 			oneOf(db).startTransaction(false);
@@ -246,6 +246,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn3, messageId2);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 
 			// Get messages to share
@@ -253,6 +254,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn4));
 			oneOf(db).getMessagesToShare(txn4, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 		}});
 
@@ -263,12 +265,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.startService();
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
 	}
 
 	@Test
@@ -292,12 +288,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getMessagesToValidate(txn, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// No pending messages to deliver
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn1));
 			oneOf(db).getPendingMessages(txn1, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 
 			// Get messages to share
@@ -305,6 +303,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn2));
 			oneOf(db).getMessagesToShare(txn2, clientId);
 			will(returnValue(Collections.singletonList(messageId)));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Share message and get dependencies
 			oneOf(db).startTransaction(false);
@@ -312,6 +311,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			oneOf(db).setMessageShared(txn3, messageId);
 			oneOf(db).getMessageDependencies(txn3, messageId);
 			will(returnValue(Collections.singletonMap(messageId2, DELIVERED)));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Share dependency
 			oneOf(db).startTransaction(false);
@@ -319,6 +319,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			oneOf(db).setMessageShared(txn4, messageId2);
 			oneOf(db).getMessageDependencies(txn4, messageId2);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 		}});
 
@@ -329,12 +330,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.startService();
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
 	}
 
 	@Test
@@ -355,6 +350,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -378,6 +374,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(Collections.emptyMap()));
 			// Share message
 			oneOf(db).setMessageShared(txn1, messageId);
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Share dependencies
 			oneOf(db).startTransaction(false);
@@ -385,6 +382,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			oneOf(db).setMessageShared(txn2, messageId1);
 			oneOf(db).getMessageDependencies(txn2, messageId1);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 		}});
 
@@ -395,10 +393,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
 	}
 
 	@Test
@@ -423,12 +417,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getMessagesToValidate(txn, clientId);
 			will(returnValue(Arrays.asList(messageId, messageId1)));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Load the first raw message - *gasp* it's gone!
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn1));
 			oneOf(db).getRawMessage(txn1, messageId);
 			will(throwException(new NoSuchMessageException()));
+			never(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Load the second raw message and group
 			oneOf(db).startTransaction(true);
@@ -437,6 +433,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(raw));
 			oneOf(db).getGroup(txn2, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Validate the second message: invalid
 			oneOf(validator).validateMessage(message1, group);
@@ -452,18 +449,21 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Recursively invalidate dependents
 			oneOf(db).getMessageDependents(txn3, messageId1);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Get pending messages to deliver
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn4));
 			oneOf(db).getPendingMessages(txn4, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 			// Get messages to share
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn5));
 			oneOf(db).getMessagesToShare(txn5, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn5);
 			oneOf(db).endTransaction(txn5);
 		}});
 
@@ -474,13 +474,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.startService();
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertFalse(txn1.isComplete()); // Aborted due to NoSuchMessageException
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
-		assertTrue(txn5.isComplete());
 	}
 
 	@Test
@@ -505,6 +498,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getMessagesToValidate(txn, clientId);
 			will(returnValue(Arrays.asList(messageId, messageId1)));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Load the first raw message
 			oneOf(db).startTransaction(true);
@@ -514,6 +508,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Load the group - *gasp* it's gone!
 			oneOf(db).getGroup(txn1, groupId);
 			will(throwException(new NoSuchGroupException()));
+			never(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Load the second raw message and group
 			oneOf(db).startTransaction(true);
@@ -522,6 +517,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(raw));
 			oneOf(db).getGroup(txn2, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Validate the second message: invalid
 			oneOf(validator).validateMessage(message1, group);
@@ -537,18 +533,21 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Recursively invalidate dependents
 			oneOf(db).getMessageDependents(txn3, messageId1);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Get pending messages to deliver
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn4));
 			oneOf(db).getPendingMessages(txn4, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 			// Get messages to share
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn5));
 			oneOf(db).getMessagesToShare(txn5, clientId);
 			will(returnValue(Collections.emptyList()));
+			oneOf(db).commitTransaction(txn5);
 			oneOf(db).endTransaction(txn5);
 		}});
 
@@ -559,13 +558,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.startService();
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertFalse(txn1.isComplete()); // Aborted due to NoSuchGroupException
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
-		assertTrue(txn5.isComplete());
 	}
 
 	@Test
@@ -585,6 +577,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -602,6 +595,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 		}});
 
@@ -612,9 +606,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
 	}
 
 	@Test
@@ -655,6 +646,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -668,6 +660,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(Collections.singletonMap(messageId1, UNKNOWN)));
 			oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
 			oneOf(db).setMessageState(txn1, messageId, PENDING);
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 		}});
 
@@ -678,9 +671,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
 	}
 
 	@Test
@@ -701,6 +691,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -722,6 +713,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 		}});
 
@@ -732,9 +724,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
 	}
 
 	@Test
@@ -756,6 +745,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -777,6 +767,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Recursively invalidate dependents
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(Collections.singletonMap(messageId2, UNKNOWN)));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Invalidate dependent in a new transaction
 			oneOf(db).startTransaction(false);
@@ -788,6 +779,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			oneOf(db).deleteMessageMetadata(txn2, messageId2);
 			oneOf(db).getMessageDependents(txn2, messageId2);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 		}});
 
@@ -798,10 +790,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
 	}
 
 	@Test
@@ -831,6 +819,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: invalid
 			oneOf(validator).validateMessage(message, group);
@@ -846,6 +835,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// The message has two dependents: 1 and 2
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(twoDependents));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Invalidate message 1
 			oneOf(db).startTransaction(false);
@@ -858,6 +848,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 1 has one dependent: 3
 			oneOf(db).getMessageDependents(txn2, messageId1);
 			will(returnValue(Collections.singletonMap(messageId3, PENDING)));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Invalidate message 2
 			oneOf(db).startTransaction(false);
@@ -870,6 +861,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 2 has one dependent: 3 (same dependent as 1)
 			oneOf(db).getMessageDependents(txn3, messageId2);
 			will(returnValue(Collections.singletonMap(messageId3, PENDING)));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Invalidate message 3 (via 1)
 			oneOf(db).startTransaction(false);
@@ -882,12 +874,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 3 has one dependent: 4
 			oneOf(db).getMessageDependents(txn4, messageId3);
 			will(returnValue(Collections.singletonMap(messageId4, PENDING)));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 			// Invalidate message 3 (again, via 2)
 			oneOf(db).startTransaction(false);
 			will(returnValue(txn5));
 			oneOf(db).getMessageState(txn5, messageId3);
 			will(returnValue(INVALID)); // Already invalidated
+			oneOf(db).commitTransaction(txn5);
 			oneOf(db).endTransaction(txn5);
 			// Invalidate message 4 (via 1 and 3)
 			oneOf(db).startTransaction(false);
@@ -900,6 +894,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 4 has no dependents
 			oneOf(db).getMessageDependents(txn6, messageId4);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn6);
 			oneOf(db).endTransaction(txn6);
 		}});
 
@@ -910,10 +905,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
 	}
 
 	@Test
@@ -950,6 +941,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -967,6 +959,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// The message has two pending dependents: 1 and 2
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(twoDependents));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Check whether message 1 is ready to be delivered
 			oneOf(db).startTransaction(false);
@@ -991,6 +984,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 1 has one pending dependent: 3
 			oneOf(db).getMessageDependents(txn2, messageId1);
 			will(returnValue(Collections.singletonMap(messageId3, PENDING)));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Check whether message 2 is ready to be delivered
 			oneOf(db).startTransaction(false);
@@ -1015,6 +1009,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 2 has one pending dependent: 3 (same dependent as 1)
 			oneOf(db).getMessageDependents(txn3, messageId2);
 			will(returnValue(Collections.singletonMap(messageId3, PENDING)));
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 			// Check whether message 3 is ready to be delivered (via 1)
 			oneOf(db).startTransaction(false);
@@ -1038,12 +1033,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 3 has one pending dependent: 4
 			oneOf(db).getMessageDependents(txn4, messageId3);
 			will(returnValue(Collections.singletonMap(messageId4, PENDING)));
+			oneOf(db).commitTransaction(txn4);
 			oneOf(db).endTransaction(txn4);
 			// Check whether message 3 is ready to be delivered (again, via 2)
 			oneOf(db).startTransaction(false);
 			will(returnValue(txn5));
 			oneOf(db).getMessageState(txn5, messageId3);
 			will(returnValue(DELIVERED)); // Already delivered
+			oneOf(db).commitTransaction(txn5);
 			oneOf(db).endTransaction(txn5);
 			// Check whether message 4 is ready to be delivered (via 1 and 3)
 			oneOf(db).startTransaction(false);
@@ -1068,6 +1065,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Message 4 has no pending dependents
 			oneOf(db).getMessageDependents(txn6, messageId4);
 			will(returnValue(Collections.emptyMap()));
+			oneOf(db).commitTransaction(txn6);
 			oneOf(db).endTransaction(txn6);
 		}});
 
@@ -1078,14 +1076,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
-		assertTrue(txn3.isComplete());
-		assertTrue(txn4.isComplete());
-		assertTrue(txn5.isComplete());
-		assertTrue(txn6.isComplete());
 	}
 
 	@Test
@@ -1109,6 +1099,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -1126,6 +1117,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			// Get any pending dependents
 			oneOf(db).getMessageDependents(txn1, messageId);
 			will(returnValue(Collections.singletonMap(messageId1, PENDING)));
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Check whether the pending dependent is ready to be delivered
 			oneOf(db).startTransaction(false);
@@ -1134,6 +1126,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(PENDING));
 			oneOf(db).getMessageDependencies(txn2, messageId1);
 			will(returnValue(twoDependencies));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 		}});
 
@@ -1144,10 +1137,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
-		assertTrue(txn2.isComplete());
 	}
 
 	@Test
@@ -1172,6 +1161,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(txn));
 			oneOf(db).getGroup(txn, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn);
 			oneOf(db).endTransaction(txn);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message, group);
@@ -1185,12 +1175,14 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(Collections.singletonMap(messageId1, UNKNOWN)));
 			oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
 			oneOf(db).setMessageState(txn1, messageId, PENDING);
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 			// Second message is coming in
 			oneOf(db).startTransaction(true);
 			will(returnValue(txn2));
 			oneOf(db).getGroup(txn2, groupId);
 			will(returnValue(group));
+			oneOf(db).commitTransaction(txn2);
 			oneOf(db).endTransaction(txn2);
 			// Validate the message: valid
 			oneOf(validator).validateMessage(message1, group);
@@ -1204,6 +1196,7 @@ public class ValidationManagerImplTest extends BriarTestCase {
 			will(returnValue(Collections.singletonMap(messageId, PENDING)));
 			oneOf(db).mergeMessageMetadata(txn3, messageId1, metadata);
 			oneOf(db).setMessageState(txn3, messageId1, PENDING);
+			oneOf(db).commitTransaction(txn3);
 			oneOf(db).endTransaction(txn3);
 		}});
 
@@ -1215,9 +1208,6 @@ public class ValidationManagerImplTest extends BriarTestCase {
 		vm.eventOccurred(new MessageAddedEvent(message1, contactId));
 
 		context.assertIsSatisfied();
-
-		assertTrue(txn.isComplete());
-		assertTrue(txn1.isComplete());
 	}
 
 }
diff --git a/briar-tests/src/org/briarproject/transport/TransportKeyManagerTest.java b/briar-tests/src/org/briarproject/transport/TransportKeyManagerTest.java
index 4a32490c95..b97d1786c3 100644
--- a/briar-tests/src/org/briarproject/transport/TransportKeyManagerTest.java
+++ b/briar-tests/src/org/briarproject/transport/TransportKeyManagerTest.java
@@ -39,7 +39,6 @@ import static org.briarproject.util.ByteUtils.MAX_32_BIT_UNSIGNED;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
 
 public class TransportKeyManagerTest extends BriarTestCase {
 
@@ -453,13 +452,13 @@ public class TransportKeyManagerTest extends BriarTestCase {
 			oneOf(scheduler).schedule(with(any(Runnable.class)),
 					with(rotationPeriodLength), with(MILLISECONDS));
 			// Commit the key rotation transaction
+			oneOf(db).commitTransaction(txn1);
 			oneOf(db).endTransaction(txn1);
 		}});
 
 		TransportKeyManager transportKeyManager = new TransportKeyManager(db,
 				crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
 		transportKeyManager.start(txn);
-		assertTrue(txn1.isComplete());
 
 		context.assertIsSatisfied();
 	}
-- 
GitLab