Source:
public void testConcurrentUpserts() throws Exception { int nThreads = 4; final int batchSize = 200; final int nRows = 51; final int nIndexValues = 23; final String tableName = generateUniqueName(); final String indexName = generateUniqueName(); Connection conn = DriverManager.getConnection(getUrl()); conn.createStatement().execute("CREATE TABLE " + tableName + "(k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 INTEGER, CONSTRAINT pk PRIMARY KEY (k1,k2)) COLUMN_ENCODED_BYTES = 0, VERSIONS=1"); TestUtil.addCoprocessor(conn, tableName, DelayingRegionObserver.class); conn.createStatement().execute("CREATE INDEX " + indexName + " ON " + tableName + "(v1)"); final CountDownLatch doneSignal = new CountDownLatch(nThreads); Runnable[] runnables = new Runnable[nThreads]; for (int i = 0; i < nThreads; i++) { runnables[i] = new Runnable() { @Override public void run() { try { Connection conn = DriverManager.getConnection(getUrl()); for (int i = 0; i < 5000; i++) { boolean isNull = RAND.nextBoolean(); int randInt = RAND.nextInt() % nIndexValues; conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES (" + (i % nRows) + ", 0, " + (isNull ? null : randInt) + ")"); if ((i % batchSize) == 0) { conn.commit(); } } conn.commit(); } catch (SQLException e) { throw new RuntimeException(e); } finally { doneSignal.countDown(); } } }; } for (int i = 0; i < nThreads; i++) { Thread t = new Thread(runnables[i]); t.start(); } assertTrue("Ran out of time", doneSignal.await(120, TimeUnit.SECONDS)); long actualRowCount = IndexScrutiny.scrutinizeIndex(conn, tableName, indexName); assertEquals(nRows, actualRowCount); }

Target:
public void testConcurrentUpserts() throws Exception { int nThreads = 4; final int batchSize = 200; final int nRows = 51; final int nIndexValues = 23; final String tableName = generateUniqueName(); final String indexName = generateUniqueName(); Connection conn = DriverManager.getConnection(getUrl()); conn.createStatement().execute("CREATE TABLE " + tableName + "(k1 INTEGER NOT NULL, k2 INTEGER NOT NULL, v1 INTEGER, CONSTRAINT pk PRIMARY KEY (k1,k2)) COLUMN_ENCODED_BYTES = 0, VERSIONS=1"); TestUtil.addCoprocessor(conn, tableName, DelayingRegionObserver.class); conn.createStatement().execute("CREATE INDEX " + indexName + " ON " + tableName + "(v1)"); final CountDownLatch doneSignal = new CountDownLatch(nThreads); Runnable[] runnables = new Runnable[nThreads]; for (int i = 0; i < nThreads; i++) { runnables[i] = new Runnable() { @Override public void run() { try { Connection conn = DriverManager.getConnection(getUrl()); for (int i = 0; i < 10000; i++) { boolean isNull = RAND.nextBoolean(); int randInt = RAND.nextInt() % nIndexValues; conn.createStatement().execute("UPSERT INTO " + tableName + " VALUES (" + (i % nRows) + ", 0, " + (isNull ? null : randInt) + ")"); if ((i % batchSize) == 0) { conn.commit(); } } conn.commit(); } catch (SQLException e) { throw new RuntimeException(e); } finally { doneSignal.countDown(); } } }; } for (int i = 0; i < nThreads; i++) { Thread t = new Thread(runnables[i]); t.start(); } assertTrue("Ran out of time", doneSignal.await(120, TimeUnit.SECONDS)); long actualRowCount = IndexScrutiny.scrutinizeIndex(conn, tableName, indexName); assertEquals(nRows, actualRowCount); }