4444 * @param <T> buffer type
4545 */
4646public final class Txn <T > implements AutoCloseable {
47-
47+
4848 private static final MemoryManager MEM_MGR = RUNTIME .getMemoryManager ();
49+ private final Env <T > env ;
4950 private final T k ;
5051 private final Txn <T > parent ;
5152 private final BufferProxy <T > proxy ;
@@ -57,9 +58,10 @@ public final class Txn<T> implements AutoCloseable {
5758 private final boolean readOnly ;
5859 private State state ;
5960 private final T v ;
60-
61+
6162 Txn (final Env <T > env , final Txn <T > parent , final BufferProxy <T > proxy ,
6263 final TxnFlags ... flags ) {
64+ this .env = env ;
6365 this .proxy = proxy ;
6466 final int flagsMask = mask (flags );
6567 this .readOnly = isSet (flagsMask , MDB_RDONLY_TXN );
@@ -74,14 +76,14 @@ public final class Txn<T> implements AutoCloseable {
7476 final Pointer txnParentPtr = parent == null ? null : parent .ptr ;
7577 checkRc (LIB .mdb_txn_begin (env .pointer (), txnParentPtr , flagsMask , txnPtr ));
7678 ptr = txnPtr .getPointer (0 );
77-
79+
7880 this .k = proxy .allocate ();
7981 this .v = proxy .allocate ();
8082 ptrKey = MEM_MGR .allocateTemporary (MDB_VAL_STRUCT_SIZE , false );
8183 ptrKeyAddr = ptrKey .address ();
8284 ptrVal = MEM_MGR .allocateTemporary (MDB_VAL_STRUCT_SIZE , false );
8385 ptrValAddr = ptrVal .address ();
84-
86+
8587 state = READY ;
8688 }
8789
@@ -113,6 +115,7 @@ public void close() {
113115 proxy .deallocate (k );
114116 proxy .deallocate (v );
115117 state = RELEASED ;
118+ env .txnRelease (this );
116119 }
117120
118121 /**
@@ -199,19 +202,19 @@ public void reset() {
199202 public T val () {
200203 return v ;
201204 }
202-
205+
203206 void checkReadOnly () throws ReadOnlyRequiredException {
204207 if (!readOnly ) {
205208 throw new ReadOnlyRequiredException ();
206209 }
207210 }
208-
211+
209212 void checkReady () throws NotReadyException {
210213 if (state != READY ) {
211214 throw new NotReadyException ();
212215 }
213216 }
214-
217+
215218 void checkWritesAllowed () throws ReadWriteRequiredException {
216219 if (readOnly ) {
217220 throw new ReadWriteRequiredException ();
@@ -226,7 +229,7 @@ void checkWritesAllowed() throws ReadWriteRequiredException {
226229 State getState () {
227230 return state ;
228231 }
229-
232+
230233 void keyIn (final T key ) {
231234 proxy .in (key , ptrKey , ptrKeyAddr );
232235 if (SHOULD_CHECK ) {
@@ -236,23 +239,23 @@ void keyIn(final T key) {
236239 }
237240 }
238241 }
239-
242+
240243 void keyOut () {
241244 proxy .out (k , ptrKey , ptrKeyAddr );
242245 }
243-
246+
244247 Pointer pointer () {
245248 return ptr ;
246249 }
247-
250+
248251 Pointer pointerKey () {
249252 return ptrKey ;
250253 }
251-
254+
252255 Pointer pointerVal () {
253256 return ptrVal ;
254257 }
255-
258+
256259 void valIn (final T val , final boolean zeroLenValAllowed ) {
257260 proxy .in (val , ptrVal , ptrValAddr );
258261 if (SHOULD_CHECK && !zeroLenValAllowed ) {
@@ -262,14 +265,14 @@ void valIn(final T val, final boolean zeroLenValAllowed) {
262265 }
263266 }
264267 }
265-
268+
266269 void valIn (final int size ) {
267270 if (size <= 0 ) {
268271 throw new IndexOutOfBoundsException ("Reservation must be > 0 bytes" );
269272 }
270273 proxy .in (v , size , ptrVal , ptrValAddr );
271274 }
272-
275+
273276 void valOut () {
274277 proxy .out (v , ptrVal , ptrValAddr );
275278 }
@@ -278,10 +281,10 @@ void valOut() {
278281 * Transaction must abort, has a child, or is invalid.
279282 */
280283 public static final class BadException extends LmdbNativeException {
281-
284+
282285 static final int MDB_BAD_TXN = -30_782 ;
283286 private static final long serialVersionUID = 1L ;
284-
287+
285288 BadException () {
286289 super (MDB_BAD_TXN , "Transaction must abort, has a child, or is invalid" );
287290 }
@@ -291,10 +294,10 @@ public static final class BadException extends LmdbNativeException {
291294 * Invalid reuse of reader locktable slot.
292295 */
293296 public static final class BadReaderLockException extends LmdbNativeException {
294-
297+
295298 static final int MDB_BAD_RSLOT = -30_783 ;
296299 private static final long serialVersionUID = 1L ;
297-
300+
298301 BadReaderLockException () {
299302 super (MDB_BAD_RSLOT , "Invalid reuse of reader locktable slot" );
300303 }
@@ -304,7 +307,7 @@ public static final class BadReaderLockException extends LmdbNativeException {
304307 * The proposed R-W transaction is incompatible with a R-O Env.
305308 */
306309 public static class EnvIsReadOnly extends LmdbException {
307-
310+
308311 private static final long serialVersionUID = 1L ;
309312
310313 /**
@@ -319,7 +322,7 @@ public EnvIsReadOnly() {
319322 * The proposed transaction is incompatible with its parent transaction.
320323 */
321324 public static class IncompatibleParent extends LmdbException {
322-
325+
323326 private static final long serialVersionUID = 1L ;
324327
325328 /**
@@ -334,7 +337,7 @@ public IncompatibleParent() {
334337 * Transaction is not in a READY state.
335338 */
336339 public static final class NotReadyException extends LmdbException {
337-
340+
338341 private static final long serialVersionUID = 1L ;
339342
340343 /**
@@ -349,7 +352,7 @@ public NotReadyException() {
349352 * The current transaction has not been reset.
350353 */
351354 public static class NotResetException extends LmdbException {
352-
355+
353356 private static final long serialVersionUID = 1L ;
354357
355358 /**
@@ -364,7 +367,7 @@ public NotResetException() {
364367 * The current transaction is not a read-only transaction.
365368 */
366369 public static class ReadOnlyRequiredException extends LmdbException {
367-
370+
368371 private static final long serialVersionUID = 1L ;
369372
370373 /**
@@ -379,7 +382,7 @@ public ReadOnlyRequiredException() {
379382 * The current transaction is not a read-write transaction.
380383 */
381384 public static class ReadWriteRequiredException extends LmdbException {
382-
385+
383386 private static final long serialVersionUID = 1L ;
384387
385388 /**
@@ -394,7 +397,7 @@ public ReadWriteRequiredException() {
394397 * The current transaction has already been reset.
395398 */
396399 public static class ResetException extends LmdbException {
397-
400+
398401 private static final long serialVersionUID = 1L ;
399402
400403 /**
@@ -409,10 +412,10 @@ public ResetException() {
409412 * Transaction has too many dirty pages.
410413 */
411414 public static final class TxFullException extends LmdbNativeException {
412-
415+
413416 static final int MDB_TXN_FULL = -30_788 ;
414417 private static final long serialVersionUID = 1L ;
415-
418+
416419 TxFullException () {
417420 super (MDB_TXN_FULL , "Transaction has too many dirty pages" );
418421 }
@@ -424,5 +427,5 @@ public static final class TxFullException extends LmdbNativeException {
424427 enum State {
425428 READY , DONE , RESET , RELEASED
426429 }
427-
430+
428431}
0 commit comments