Skip to content

3.11.0 regression: documents inserted in a transaction expire immediately #48

@ianprime0509

Description

@ianprime0509

As of Java SDK 3.11.0, it seems that documents inserted in a transaction are set with an expiry of the current time, making them expire immediately and quickly get removed from the collection. Here's a simple example program to demonstrate:

package com.example;

import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.json.JsonObject;
import com.couchbase.client.java.kv.GetOptions;
import org.testcontainers.couchbase.BucketDefinition;
import org.testcontainers.couchbase.CouchbaseContainer;
import org.testcontainers.utility.DockerImageName;

public class TransactionalInsert {
    private static final DockerImageName IMAGE = DockerImageName
            .parse("couchbase:enterprise-7.6.5@sha256:f25b85b64066ad479c18ea5d1b4fb24e921979652f9a2cc50049a9dda04a40a8")
            .asCompatibleSubstituteFor("couchbase/server");

    public static void main(String[] args) throws Exception {
        var container = new CouchbaseContainer(IMAGE).withBucket(new BucketDefinition("MyBucket"));
        container.start();
        var cluster = Cluster.connect(container.getConnectionString(), container.getUsername(), container.getPassword());
        var bucket = cluster.bucket("MyBucket");
        var collection = bucket.defaultCollection();
        cluster.transactions().run(ctx ->
                ctx.insert(collection, "test-document", JsonObject.create().put("key", "value")));

        var document = collection.get("test-document", GetOptions.getOptions().withExpiry(true));
        System.out.println("Document immediately after insert: " + document);

        Thread.sleep(60_000);

        var laterDocument = collection.get("test-document", GetOptions.getOptions().withExpiry(true));
        System.out.println("Document after waiting for expiry cleanup: " + laterDocument);
    }
}
Dependencies
<dependency>
    <groupId>com.couchbase.client</groupId>
    <artifactId>java-client</artifactId>
    <version>3.11.0</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.28</version>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers-couchbase</artifactId>
    <version>2.0.3</version>
</dependency>

Using SDK version 3.11.0 as above results in this output (only relevant parts included):

Document immediately after insert: GetResult{content={"key":"value"}, flags=0x2000000, cas=0x1892acef6da70000, expiry=Optional[2026-02-09T20:09:07Z]}
Exception in thread "main" com.couchbase.client.core.error.DocumentNotFoundException: Document with the given id not found {"completed":true,"coreId":"0xe3f6717000000001","idempotent":true,"lastChannelId":"E3F6717000000001/0000000088CFCAE1","lastDispatchedFrom":"127.0.0.1:50586","lastDispatchedTo":"localhost:50490","requestId":1068,"requestType":"SubdocGetRequest","retried":0,"serverDuration":6,"service":{"bucket":"MyBucket","collection":"_default","documentId":"test-document","errorCode":{"description":"Not Found","name":"KEY_ENOENT"},"opaque":"0x446","scope":"_default","type":"kv","vbucket":863},"status":"NOT_FOUND","timeoutMs":2500,"timings":{"dispatchMicros":841,"totalDispatchMicros":841,"totalServerMicros":0,"totalMicros":1443,"serverMicros":0}}

Using SDK version 3.10.1 results in the expected output:

Document immediately after insert: GetResult{content={"key":"value"}, flags=0x2000000, cas=0x1892ad5bfc3f0000, expiry=Optional.empty}
Document after waiting for expiry cleanup: GetResult{content={"key":"value"}, flags=0x2000000, cas=0x1892ad5bfc3f0000, expiry=Optional.empty}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions