package org.infinispan.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.transaction.TransactionManager;

import org.infinispan.Cache;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.demo.tx.TxWriter;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.transaction.LockingMode;
import org.infinispan.transaction.TransactionMode;
import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;

public class EmbeddedTx {

    private static final int writerCount = 2;
    private static final int updateCoutn = 10;
    
    public static void main(String[] args) throws Exception {
        Cache<String, String> cache = embeddedTxCache();
        runConcurentWrites(cache, "key");
    }
    
    public static void runConcurentWrites(Cache<String, String> cache, String key) throws Exception {
        TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
        tm.begin();
        cache.put(key, "init value"); // avoid failed NPE in replace method
        tm.commit();
        
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i = 0; i < writerCount; i++) {
            es.submit(new TxWriter(cache, key, updateCoutn));
        }
        es.shutdown();
        es.awaitTermination(10, TimeUnit.SECONDS);
    }
    
    public static Cache<String, String> embeddedTxCache() {
        ConfigurationBuilder cb = new ConfigurationBuilder();
        cb
        .locking()
            .isolationLevel(IsolationLevel.READ_COMMITTED)
        .transaction()
            .lockingMode(LockingMode.OPTIMISTIC)
            .autoCommit(false) //we will handle transaction boundaries manually
            .completedTxTimeout(60_000)
            .transactionMode(TransactionMode.TRANSACTIONAL)
            .transactionManagerLookup(new GenericTransactionManagerLookup()); // defualt to EmbeddedTransactionManagerLookup if no other TM lookup is found
        EmbeddedCacheManager cm = new DefaultCacheManager(cb.build());
        return cm.getCache();
    }
}

@@ -221,16 +221,95 @@
 .Cache;%0A
+import org.infinispan.cdi.embedded.event.cachemanager.CacheManagerEventBridge;%0A
 import o
@@ -933,48 +933,709 @@
     
-Cache%3CString, String%3E cache = embeddedTx
+System.out.println(%22OPTIMISTIC, READ COMMITED%22);%0A        runConcurentOptimisticsTx();%0A        System.out.println(%22PESSIMISTIC, REPEATABLE READ%22);%0A        runConcurentPessimisticTx();%0A    %7D%0A    %0A    public static void runConcurentOptimisticsTx() throws Exception %7B%0A        EmbeddedCacheManager cm = getTxCache(IsolationLevel.READ_COMMITTED, LockingMode.OPTIMISTIC);%0A        Cache%3CString, String%3E cache = cm.getCache();%0A        runConcurrentWrites(cache);%0A        cm.stop();%0A    %7D%0A    %0A    public static void runConcurentPessimisticTx() throws Exception %7B%0A        EmbeddedCacheManager cm = getTxCache(IsolationLevel.REPEATABLE_READ, LockingMode.PESSIMISTIC);%0A        Cache%3CString, String%3E cache = cm.get
 Cach
@@ -1648,32 +1648,33 @@
        runConcur
+r
 entWrites(cache,
@@ -1676,15 +1676,27 @@
 ache
-, %22key%22
+);%0A        cm.stop(
 );%0A 
@@ -1737,16 +1737,17 @@
 unConcur
+r
 entWrite
@@ -1779,20 +1779,8 @@
 ache
-, String key
 ) th
@@ -1788,32 +1788,60 @@
 ows Exception %7B%0A
+        String key = %22key%22;%0A
         Transact
@@ -2321,46 +2321,85 @@
 tic 
-Cache%3CString, String%3E embeddedTxCache(
+EmbeddedCacheManager getTxCache(IsolationLevel isolation, LockingMode locking
 ) %7B%0A
@@ -2518,25 +2518,25 @@
 onLevel(
-I
+i
 solation
 Level.RE
@@ -2527,36 +2527,16 @@
 solation
-Level.READ_COMMITTED
 )%0A      
@@ -2577,38 +2577,23 @@
 ingMode(
-L
+l
 ocking
-Mode.OPTIMISTIC
 )%0A      
@@ -2934,33 +2934,14 @@
     
-EmbeddedCacheManager cm =
+return
  new
@@ -2978,38 +2978,8 @@
 ));%0A
-        return cm.getCache();%0A
     

Add pessimistic locking with repeatable read example