HHH-5859 - Upgraded to 4.2.0.CR1

Apart from upgrading Infinispan, test transaction manager code has been
changed so that read only transactions are not committed twice.
This commit is contained in:
Galder Zamarreño 2011-01-24 19:53:35 +01:00
parent f26e8cdd2c
commit 5dfcdae14d
7 changed files with 173 additions and 28 deletions

View File

@ -1,5 +1,5 @@
dependencies {
infinispanVersion = '4.2.0.CR4'
infinispanVersion = '4.2.1.CR1'
jnpVersion = '5.0.3.GA'
compile(project(':hibernate-core'))

View File

@ -43,6 +43,8 @@ public class BasicTransactionalTestCase extends SingleNodeTestCase {
commitOrRollbackTx();
}
log.info("Entry persisted, let's load and delete it.");
beginTx();
try {
Session s = openSession();
@ -246,7 +248,7 @@ public class BasicTransactionalTestCase extends SingleNodeTestCase {
}
public void testQueryCache() throws Exception {
Session s = null;
Session s;
Item item = new Item("chris", "Chris's Item");
beginTx();

View File

@ -175,6 +175,7 @@ public class ConcurrentWriteTest extends SingleNodeTestCase {
assertEquals(customerSlcs.getElementCountInMemory(), 1);
assertEquals(customerSlcs.getEntries().size(), 1);
log.info("Add contact to customer {0}", customerId);
SecondLevelCacheStatistics contactsCollectionSlcs = getEnvironment().getSessionFactory()
.getStatistics().getSecondLevelCacheStatistics(Customer.class.getName() + ".contacts");
assertEquals(1, contactsCollectionSlcs.getPutCount());

View File

@ -159,16 +159,11 @@ public class ClassLoaderTestDAO {
public Account getAccount(Integer id) throws Exception {
log.debug("Getting account " + id);
tm.begin();
Session session = sessionFactory.openSession();
try {
Session session = sessionFactory.getCurrentSession();
Account acct = (Account) session.get(acctClass, id);
tm.commit();
return acct;
} catch (Exception e) {
log.error("rolling back", e);
tm.rollback();
throw e;
return (Account) session.get(acctClass, id);
} finally {
session.close();
}
}

View File

@ -47,6 +47,8 @@ import org.infinispan.util.logging.LogFactory;
/**
* SimpleJtaTransactionImpl variant that works with DualNodeTransactionManagerImpl.
*
* TODO: Merge with single node transaction manager
*
* @author Brian Stansberry
*/
@ -77,12 +79,12 @@ public class DualNodeJtaTransactionImpl implements Transaction {
rollback();
} else {
status = Status.STATUS_PREPARING;
for (int i = 0; i < synchronizations.size(); i++) {
Synchronization s = (Synchronization) synchronizations.get(i);
s.beforeCompletion();
}
if (!runXaResourcePrepare()) {
status = Status.STATUS_ROLLING_BACK;
} else {
@ -100,7 +102,6 @@ public class DualNodeJtaTransactionImpl implements Transaction {
throw new SystemException();
}
}
runXaResourceCommitTx();
@ -168,7 +169,7 @@ public class DualNodeJtaTransactionImpl implements Transaction {
public boolean enlistResource(XAResource xaResource) throws RollbackException,
IllegalStateException, SystemException {
enlistedResources.add(xaResource);
enlistedResources.add(new WrappedXaResource(xaResource));
try {
xaResource.start(xid, 0);
} catch (XAException e) {
@ -182,11 +183,11 @@ public class DualNodeJtaTransactionImpl implements Transaction {
SystemException {
throw new SystemException("not supported");
}
public Collection<XAResource> getEnlistedResources() {
return enlistedResources;
}
private boolean runXaResourcePrepare() throws SystemException {
Collection<XAResource> resources = getEnlistedResources();
for (XAResource res : resources) {
@ -194,7 +195,7 @@ public class DualNodeJtaTransactionImpl implements Transaction {
res.prepare(xid);
} catch (XAException e) {
log.trace("The resource wants to rollback!", e);
throw new SystemException(e.getMessage());
return false;
} catch (Throwable th) {
log.error("Unexpected error from resource manager!", th);
throw new SystemException(th.getMessage());
@ -202,7 +203,7 @@ public class DualNodeJtaTransactionImpl implements Transaction {
}
return true;
}
private void runXaResourceRollback() {
Collection<XAResource> resources = getEnlistedResources();
for (XAResource res : resources) {
@ -226,7 +227,7 @@ public class DualNodeJtaTransactionImpl implements Transaction {
}
return true;
}
private static class DualNodeJtaTransactionXid implements Xid {
private static AtomicInteger txIdCounter = new AtomicInteger(0);
private int id = txIdCounter.incrementAndGet();
@ -250,4 +251,68 @@ public class DualNodeJtaTransactionImpl implements Transaction {
'}';
}
}
private class WrappedXaResource implements XAResource {
private final XAResource xaResource;
private int prepareResult;
public WrappedXaResource(XAResource xaResource) {
this.xaResource = xaResource;
}
@Override
public void commit(Xid xid, boolean b) throws XAException {
// Commit only if not read only.
if (prepareResult != XAResource.XA_RDONLY)
xaResource.commit(xid, b);
else
log.trace("Not committing {0} due to readonly.", xid);
}
@Override
public void end(Xid xid, int i) throws XAException {
xaResource.end(xid, i);
}
@Override
public void forget(Xid xid) throws XAException {
xaResource.forget(xid);
}
@Override
public int getTransactionTimeout() throws XAException {
return xaResource.getTransactionTimeout();
}
@Override
public boolean isSameRM(XAResource xaResource) throws XAException {
return xaResource.isSameRM(xaResource);
}
@Override
public int prepare(Xid xid) throws XAException {
prepareResult = xaResource.prepare(xid);
return prepareResult;
}
@Override
public Xid[] recover(int i) throws XAException {
return xaResource.recover(i);
}
@Override
public void rollback(Xid xid) throws XAException {
xaResource.rollback(xid);
}
@Override
public boolean setTransactionTimeout(int i) throws XAException {
return xaResource.setTransactionTimeout(i);
}
@Override
public void start(Xid xid, int i) throws XAException {
xaResource.start(xid, i);
}
}
}

View File

@ -35,13 +35,16 @@ import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.hibernate.test.cache.infinispan.tm.XaTransactionManagerImpl;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
/**
* Variant of SimpleJtaTransactionManagerImpl that doesn't use a VM-singleton, but rather a set of
* impls keyed by a node id.
*
*
* TODO: Merge with single node transaction manager as much as possible
*
* @author Brian Stansberry
*/
public class DualNodeJtaTransactionManagerImpl implements TransactionManager {

View File

@ -36,10 +36,12 @@ import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionImpl;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@ -51,6 +53,7 @@ import org.infinispan.util.logging.LogFactory;
*/
public class XaTransactionImpl implements Transaction {
private static final Log log = LogFactory.getLog(XaTransactionImpl.class);
private int status;
private LinkedList synchronizations;
private Connection connection; // the only resource we care about is jdbc connection
@ -63,6 +66,12 @@ public class XaTransactionImpl implements Transaction {
this.status = Status.STATUS_ACTIVE;
}
public XaTransactionImpl(XaTransactionManagerImpl jtaTransactionManager, Xid xid) {
this.jtaTransactionManager = jtaTransactionManager;
this.status = Status.STATUS_ACTIVE;
this.xid = xid;
}
public int getStatus() {
return status;
}
@ -81,7 +90,11 @@ public class XaTransactionImpl implements Transaction {
s.beforeCompletion();
}
runXaResourcePrepare();
if (!runXaResourcePrepare()) {
status = Status.STATUS_ROLLING_BACK;
} else {
status = Status.STATUS_PREPARED;
}
status = Status.STATUS_COMMITTING;
@ -110,6 +123,8 @@ public class XaTransactionImpl implements Transaction {
}
public void rollback() throws IllegalStateException, SystemException {
status = Status.STATUS_ROLLING_BACK;
runXaResourceRollback();
status = Status.STATUS_ROLLEDBACK;
if (connection != null) {
@ -122,11 +137,11 @@ public class XaTransactionImpl implements Transaction {
}
}
runXaResourceRollback();
for (int i = 0; i < synchronizations.size(); i++) {
Synchronization s = (Synchronization) synchronizations.get(i);
s.afterCompletion(status);
if (synchronizations != null) {
for (int i = 0; i < synchronizations.size(); i++) {
Synchronization s = (Synchronization) synchronizations.get(i);
s.afterCompletion(status);
}
}
// status = Status.STATUS_NO_TRANSACTION;
@ -159,7 +174,7 @@ public class XaTransactionImpl implements Transaction {
public boolean enlistResource(XAResource xaResource) throws RollbackException, IllegalStateException,
SystemException {
enlistedResources.add(xaResource);
enlistedResources.add(new WrappedXaResource(xaResource));
try {
xaResource.start(xid, 0);
} catch (XAException e) {
@ -240,4 +255,68 @@ public class XaTransactionImpl implements Transaction {
'}';
}
}
private class WrappedXaResource implements XAResource {
private final XAResource xaResource;
private int prepareResult;
public WrappedXaResource(XAResource xaResource) {
this.xaResource = xaResource;
}
@Override
public void commit(Xid xid, boolean b) throws XAException {
// Commit only if not read only.
if (prepareResult != XAResource.XA_RDONLY)
xaResource.commit(xid, b);
else
log.trace("Not committing {0} due to readonly.", xid);
}
@Override
public void end(Xid xid, int i) throws XAException {
xaResource.end(xid, i);
}
@Override
public void forget(Xid xid) throws XAException {
xaResource.forget(xid);
}
@Override
public int getTransactionTimeout() throws XAException {
return xaResource.getTransactionTimeout();
}
@Override
public boolean isSameRM(XAResource xaResource) throws XAException {
return xaResource.isSameRM(xaResource);
}
@Override
public int prepare(Xid xid) throws XAException {
prepareResult = xaResource.prepare(xid);
return prepareResult;
}
@Override
public Xid[] recover(int i) throws XAException {
return xaResource.recover(i);
}
@Override
public void rollback(Xid xid) throws XAException {
xaResource.rollback(xid);
}
@Override
public boolean setTransactionTimeout(int i) throws XAException {
return xaResource.setTransactionTimeout(i);
}
@Override
public void start(Xid xid, int i) throws XAException {
xaResource.start(xid, i);
}
}
}