/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.neo4j.remote.bolt.transaction.impl; import javax.transaction.Synchronization; import org.hibernate.ogm.datastore.neo4j.remote.bolt.impl.BoltNeo4jClient; import org.hibernate.ogm.datastore.neo4j.remote.bolt.impl.BoltNeo4jDatastoreProvider; import org.hibernate.ogm.datastore.neo4j.transaction.impl.BaseNeo4jJtaTransactionCoordinator; import org.hibernate.ogm.datastore.neo4j.transaction.impl.Neo4jSynchronization; import org.hibernate.ogm.datastore.neo4j.transaction.impl.RemoteTransactionDriver; import org.hibernate.ogm.transaction.impl.ForwardingTransactionCoordinator; import org.hibernate.resource.transaction.TransactionCoordinator; import org.neo4j.driver.v1.Driver; import org.neo4j.driver.v1.Session; import org.neo4j.driver.v1.Transaction; /** * A {@link TransactionCoordinator} for a remote Neo4j. * * Note that during a JTA transaction, Neo4j {@link Transaction} are * synchronized using the {@link Synchronization} interface. A commit to the Neo4j transaction will happen before the * end of the JTA transaction, meaning that it won't be possible to roll-back if an error happen after successful commit * to the db. * * @author Davide D'Alto */ public class BoltNeo4jJtaTransactionCoordinator extends ForwardingTransactionCoordinator implements BaseNeo4jJtaTransactionCoordinator { private final Driver driver; private Transaction tx; private Session session; public BoltNeo4jJtaTransactionCoordinator(TransactionCoordinator delegate, BoltNeo4jDatastoreProvider provider) { super( delegate ); this.driver = ( (BoltNeo4jClient) provider.getClient() ).getDriver(); } @Override public TransactionDriver getTransactionDriverControl() { return new RemoteTransactionDriver( this, super.getTransactionDriverControl() ); } @Override public void explicitJoin() { super.explicitJoin(); join(); } @Override public void pulse() { super.pulse(); join(); } @Override public void join() { if ( tx == null && delegate.isActive() && delegate.getTransactionCoordinatorBuilder().isJta() ) { beginTransaction(); delegate.getLocalSynchronizations().registerSynchronization( new Neo4jSynchronization( this ) ); } } @Override public void beginTransaction() { if ( session == null ) { session = driver.session(); } if ( tx == null ) { tx = session.beginTransaction(); } } @Override public void success() { if ( tx != null ) { try { tx.success(); tx.close(); } finally { tx = null; closeSession(); } } } @Override public void failure() { if ( tx != null ) { try { tx.failure(); tx.close(); } finally { tx = null; closeSession(); } } } private void closeSession() { try { session.close(); } finally { session = null; } } @Override public boolean isTransactionOpen() { return tx != null; } @Override public Object getTransactionId() { return tx; } }