Transaction leak if exception occurs during stopTransaction

A closed transaction remains on the thread local if an exception occurs during stopTransaction, causing all subsequent calls to fail:

    IllegalArgumentException: null (StandardPersistTitanTx.java:164)
        com.google.common.base.Preconditions.checkArgument(Preconditions.java:72)
        com.thinkaurelius.titan.graphdb.transaction.StandardPersistTitanTx.commit(StandardPersistTitanTx.java:164)
        com.thinkaurelius.titan.graphdb.blueprints.TitanBlueprintsTransaction.stopTransaction(TitanBlueprintsTransaction.java:25)
        com.thinkaurelius.titan.graphdb.blueprints.TitanBlueprintsGraph.stopTransaction(TitanBlueprintsGraph.java:36)

In this case it was caused by a lock timeout:

    com.thinkaurelius.titan.core.GraphStorageException: Exception in storage backend.
    	at com.thinkaurelius.titan.diskstorage.berkeleydb.je.BerkeleyKeyValueStore.delete(BerkeleyKeyValueStore.java:218)
    	at com.thinkaurelius.titan.diskstorage.util.KeyValueStoreAdapter.delete(KeyValueStoreAdapter.java:123)
    	at com.thinkaurelius.titan.diskstorage.util.KeyValueStoreAdapter.mutate(KeyValueStoreAdapter.java:111)
    	at com.thinkaurelius.titan.diskstorage.writeaggregation.DirectStoreMutator.mutateEdges(DirectStoreMutator.java:24)
    	at com.thinkaurelius.titan.graphdb.database.StandardTitanGraph.persist(StandardTitanGraph.java:693)
    	at com.thinkaurelius.titan.graphdb.database.StandardTitanGraph.save(StandardTitanGraph.java:642)
    	at com.thinkaurelius.titan.graphdb.transaction.StandardPersistTitanTx.commit(StandardPersistTitanTx.java:167)
    	at com.thinkaurelius.titan.graphdb.blueprints.TitanBlueprintsTransaction.stopTransaction(TitanBlueprintsTransaction.java:25)
    	at com.thinkaurelius.titan.graphdb.blueprints.TitanBlueprintsGraph.stopTransaction(TitanBlueprintsGraph.java:36)
    Caused by: com.sleepycat.je.LockTimeoutException: (JE 4.0.92) Lock expired. Locker 16139734 6719_pool-4-thread-3_Txn: waited for lock on database=edgestore LockAddr:11642210 node=12634 type=WRITE grant=WAIT_PROMOTION timeoutMillis=500 startTime=1344550894999 endTime=1344550895499
    Owners: [<LockInfo locker="2489979 6714_application-akka.actor.default-dispatcher-2_Txn" type="READ"/>, <LockInfo locker="16139734 6719_pool-4-thread-3_Txn" type="READ"/>]
    Waiters: []
    Transaction 16139734 6719_pool-4-thread-3_Txn owns LockAddr:11642210 <LockInfo locker="16139734 6719_pool-4-thread-3_Txn" type="READ"/>
    Transaction 16139734 6719_pool-4-thread-3_Txn waits for LockAddr:11642210

    	at com.sleepycat.je.txn.LockManager.newLockTimeoutException(LockManager.java:609)
    	at com.sleepycat.je.txn.LockManager.makeTimeoutMsgInternal(LockManager.java:568)
    	at com.sleepycat.je.txn.SyncedLockManager.makeTimeoutMsg(SyncedLockManager.java:76)
    	at com.sleepycat.je.txn.LockManager.lockInternal(LockManager.java:386)
    	at com.sleepycat.je.txn.LockManager.lock(LockManager.java:273)
    	at com.sleepycat.je.txn.Txn.lockInternal(Txn.java:474)
    	at com.sleepycat.je.txn.Locker.lock(Locker.java:454)
    	at com.sleepycat.je.dbi.CursorImpl.lockLNDeletedAllowed(CursorImpl.java:2566)
    	at com.sleepycat.je.dbi.CursorImpl.lockLN(CursorImpl.java:2486)
    	at com.sleepycat.je.dbi.CursorImpl.searchAndPosition(CursorImpl.java:2138)
    	at com.sleepycat.je.Cursor.searchInternal(Cursor.java:2088)
    	at com.sleepycat.je.Cursor.searchAllowPhantoms(Cursor.java:2058)
    	at com.sleepycat.je.Cursor.search(Cursor.java:1926)
    	at com.sleepycat.je.Database.deleteInternal(Database.java:776)
    	at com.sleepycat.je.Database.delete(Database.java:708)
    	at com.thinkaurelius.titan.diskstorage.berkeleydb.je.BerkeleyKeyValueStore.delete(BerkeleyKeyValueStore.java:210)
    	... 113 more