diff --git a/lib/out/w64/bin/libspreads_lmdb.dll.compressed b/lib/out/w64/bin/libspreads_lmdb.dll.compressed index a2490e5..aae8fba 100644 Binary files a/lib/out/w64/bin/libspreads_lmdb.dll.compressed and b/lib/out/w64/bin/libspreads_lmdb.dll.compressed differ diff --git a/src/Spreads.LMDB/Environment.cs b/src/Spreads.LMDB/Environment.cs index e2c40ce..8c9c130 100644 --- a/src/Spreads.LMDB/Environment.cs +++ b/src/Spreads.LMDB/Environment.cs @@ -335,18 +335,23 @@ public void Read(Action readAction, object state) /// A thread can only use one transaction at a time, plus any child transactions. Each transaction belongs to one thread. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Obsolete("Do not use in async code: A thread can only use one transaction at a time, plus any child transactions. Each transaction belongs to one thread.")] public Transaction BeginTransaction(TransactionBeginFlags flags = TransactionBeginFlags.ReadWrite) { if (((int)flags & (int)TransactionBeginFlags.ReadOnly) != 0) { - throw new InvalidOperationException("Use BeginReadOnlyTransaction for readonly transactions"); + ThrowShouldUseReadOnlyTxn(); } var impl = TransactionImpl.Create(this, flags); var txn = new Transaction(impl); return txn; } + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowShouldUseReadOnlyTxn() + { + throw new InvalidOperationException("Use BeginReadOnlyTransaction for readonly transactions"); + } + /// /// ReadOnlyTransaction transaction must be disposed ASAP to avoid LMDB environment growth and allocating garbage. /// diff --git a/src/Spreads.LMDB/Transaction.cs b/src/Spreads.LMDB/Transaction.cs index 2185cc0..31fdfdf 100644 --- a/src/Spreads.LMDB/Transaction.cs +++ b/src/Spreads.LMDB/Transaction.cs @@ -28,6 +28,7 @@ internal Transaction(TransactionImpl txn) /// All cursors opened within the transaction will be closed by this call. /// The cursors and transaction handle will be freed and must not be used again after this call. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Commit() { _impl.Commit(); @@ -38,11 +39,13 @@ public void Commit() /// All cursors opened within the transaction will be closed by this call. /// The cursors and transaction handle will be freed and must not be used again after this call. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Abort() { _impl.Abort(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { _impl.Dispose(); @@ -63,6 +66,7 @@ internal ReadOnlyTransaction(TransactionImpl txn) _impl = txn; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { _impl.Dispose(); @@ -265,29 +269,49 @@ internal static void ThrowlTransactionIsReadOnly(string message = null) public bool IsReadOnly { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _readHandle != null; } + get => _readHandle != null; } /// /// Current transaction state. /// - internal TransactionState State => _state; + internal TransactionState State + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _state; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Commit() { if (_state != TransactionState.Active) { - throw new InvalidOperationException("Transaction state is not active for commit"); + ThrowTxNotActiveOnCommit(); } + if (IsReadOnly) { - throw new InvalidOperationException("Cannot commit readonly transaction"); + ThrowTxReadOnlyOnCommit(); } - + NativeMethods.AssertExecute(NativeMethods.mdb_txn_commit(_writeHandle)); _state = TransactionState.Commited; } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowTxNotActiveOnCommit() + { + throw new InvalidOperationException("Transaction state is not active for commit"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowTxReadOnlyOnCommit() + { + throw new InvalidOperationException("Cannot commit readonly transaction"); + } + + public void Abort() { if (_state != TransactionState.Active)