# Example

To understand the concepts of *JTX* its best to see an example. To make things simpler, our transactional resource will be a simple `String` value. Let's create one such class:

```java
    public class WorkSession {

        static String persistedValue = "jodd";
        String sessionValue;
        boolean readOnly;
        int txno;            // transaction number

        public WorkSession() {    // start session in non-tx mode
        }
        public WorkSession(int txno) {    // start tx session
            this.txno = txno;
        }

        public void writeValue(String value) {
            if (txno == 0) {    // no transaction
                persistedValue = value;
                return;
            }
            // under transaction
            if (readOnly == true) {
                throw new UncheckedException();
            }
            sessionValue = value;
        }

        public String readValue() {
            if (sessionValue != null) {
                return sessionValue;
            }
            return persistedValue;
        }

        // commit
        public void done() {
            if (sessionValue != null) {
                persistedValue = sessionValue;
            }
            sessionValue = null;
        }

        // rollback
        public void back() {
            sessionValue = null;
        }
```

Now we are ready to begin our journey:)

### ResourceManager

The first thing is to create a `JtxResourceManager` for our resource. The main method to implement is `beginTransaction()`. It starts a transaction on our resource depending on transaction mode.

Since we will use `JtxTransactionManager`, propagation behavior and timeout will be already supported! Therefore, our resource manager has only to deal with isolation and read-only attribute. We will ignore isolation to make things simpler. Here is how resource manager may look like:

```java
    public class WorkResourceManager implements JtxResourceManager<WorkSession> {

        int txno = 1;

        public Class<WorkSession> getResourceType() {
            return WorkSession.class;
        }

        public WorkSession beginTransaction(JtxTransactionMode jtxMode, boolean active) {
            if (active == false) {
                return new WorkSession();
            }
            WorkSession work = new WorkSession(txno++);
            work.readOnly = jtxMode.isReadOnly();
            return work;
        }

        public void commitTransaction(WorkSession resource) {
            resource.done();
            txno--;
        }

        public void rollbackTransaction(WorkSession resource) {
            resource.back();
            txno--;
        }

        public void close() {
        }
    }
```

Quick overview of what we have done in `beginTransaction()`\\: the `active` flag tells us if real transaction should be started or we are working in auto-commit mode. When it is set, we create a transaction-aware resource. Since isolation is ignored, we only need to pass read-only flag.

### Usage

Now we are ready to use *JTX*\\:

```java
    // [1] create jtx manager and register our resource manager
    JtxTransactionManager jtxManager = new JtxTransactionManager();
    jtxManager.registerResourceManager(new WorkResourceManager());

    // [2] request jtx
    JtxTransaction jtx = manager.requestTransaction(
            new JtxTransactionMode().propagationRequired().readOnly(true));

    // [3] requrest resource i.e. start jtx
    WorkSession work = jtx.requestResource(WorkSession.class);

    // [4] work
    work.writeValue("new value");

    // [5] done
    jtx.commit();

    // [6] cleanup
    manager.close();
```

The most important thing to remember is that in step #2 we are just **requesting** a jtx transaction. Not until the next step, #3, the real transaction will be started. Again, we are **requesting** a resource, therefore, if we call it several time in a row, the same resource instance will be returned.

### Worker

*JTX* also provides `LeanJtxWorker`, a class that utilizes `JtxTransactionManager` and makes it more convenient for use when transaction is requested over different context, i.e. with transaction nesting. Basically, everything stays the same, except `LeanJtxWorker` would return `null` when new transaction is not created on its request, meaning that current transaction matches the requested transaction attributes (mostly propagation).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://db.jodd.org/jtx/example.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
