Permalink
Browse files

transactional result iterator registered as synchronization only duri…

…ng active transactions
  • Loading branch information...
DirkMahler committed Jul 4, 2017
1 parent f24ffed commit 99aad84ea6a09a2309f543ee03663f115114418b
@@ -1,12 +1,12 @@
package com.buschmais.xo.impl.transaction;
import com.buschmais.xo.api.ResultIterator;
import com.buschmais.xo.api.XOTransaction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.buschmais.xo.api.ResultIterator;
import com.buschmais.xo.api.XOTransaction;
public class TransactionalResultIterator<E> implements ResultIterator<E>, XOTransaction.Synchronization {
private ResultIterator<E> delegateIterator;
@@ -15,7 +15,7 @@
public TransactionalResultIterator(ResultIterator<E> delegateIterator, XOTransaction xoTransaction) {
this.xoTransaction = xoTransaction;
this.delegateIterator = delegateIterator;
if (xoTransaction != null) {
if (isTransactional()) {
xoTransaction.registerSynchronization(this);
}
}
@@ -79,9 +79,13 @@ public void afterCompletion(boolean committed) {
}
private void unregisterSynchronization() {
if (this.xoTransaction != null) {
if (isTransactional()) {
this.xoTransaction.unregisterSynchronization(this);
this.xoTransaction = null;
}
}
private boolean isTransactional() {
return this.xoTransaction != null && this.xoTransaction.isActive();
}
}
@@ -0,0 +1,70 @@
package com.buschmais.xo.impl;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.buschmais.xo.api.ResultIterator;
import com.buschmais.xo.api.XOTransaction;
import com.buschmais.xo.impl.transaction.TransactionalResultIterator;
@RunWith(MockitoJUnitRunner.class)
public class TransactionalResultIteratorTest {
@Mock
private ResultIterator<String> resultIterator;
@Mock
private XOTransaction xoTransaction;
@Test
public void transactional() {
when(xoTransaction.isActive()).thenReturn(true);
TransactionalResultIterator<String> transactionalResultIterator = new TransactionalResultIterator<>(resultIterator, xoTransaction);
ArgumentCaptor<XOTransaction.Synchronization> synchronizationCaptor = ArgumentCaptor.forClass(XOTransaction.Synchronization.class);
verify(xoTransaction).registerSynchronization(synchronizationCaptor.capture());
verify(xoTransaction, never()).unregisterSynchronization(synchronizationCaptor.getValue());
transactionalResultIterator.close();
verify(xoTransaction).unregisterSynchronization(synchronizationCaptor.getValue());
verify(resultIterator).close();
}
@Test
public void nonTransactional() {
when(xoTransaction.isActive()).thenReturn(false);
TransactionalResultIterator<String> transactionalResultIterator = new TransactionalResultIterator<>(resultIterator, xoTransaction);
transactionalResultIterator.close();
verify(xoTransaction, never()).registerSynchronization(any(XOTransaction.Synchronization.class));
}
@Test
public void detachResultOnCompletion() {
when(xoTransaction.isActive()).thenReturn(true);
TransactionalResultIterator<String> transactionalResultIterator = new TransactionalResultIterator<>(resultIterator, xoTransaction);
when(resultIterator.hasNext()).thenReturn(true, false);
when(resultIterator.next()).thenReturn("value");
transactionalResultIterator.beforeCompletion();
transactionalResultIterator.afterCompletion(true);
verify(resultIterator, times(2)).hasNext();
verify(resultIterator).next();
assertThat(transactionalResultIterator.hasNext(), equalTo(true));
assertThat(transactionalResultIterator.next(), equalTo("value"));
assertThat(transactionalResultIterator.hasNext(), equalTo(false));
}
}

0 comments on commit 99aad84

Please sign in to comment.