Skip to content

Commit 0ffeb3c

Browse files
committed
#80 ensure collections before transaction start
1 parent 5baea19 commit 0ffeb3c

File tree

6 files changed

+41
-42
lines changed

6 files changed

+41
-42
lines changed

src/main/java/com/arangodb/springframework/transaction/ArangoTransactionManager.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
import com.arangodb.ArangoDBException;
2424
import com.arangodb.ArangoDatabase;
25-
import com.arangodb.DbName;
2625
import com.arangodb.springframework.core.ArangoOperations;
26+
import com.arangodb.springframework.core.template.CollectionCallback;
2727
import com.arangodb.springframework.repository.query.QueryTransactionBridge;
2828
import org.springframework.beans.factory.InitializingBean;
2929
import org.springframework.lang.Nullable;
@@ -67,10 +67,10 @@ public void afterPropertiesSet() {
6767
throw new IllegalStateException("Nested transactions must not be allowed");
6868
}
6969
if (!isGlobalRollbackOnParticipationFailure()) {
70-
throw new IllegalStateException("Global rollback on participating failure is needed");
70+
throw new IllegalStateException("Global rollback on participating failure is required");
7171
}
7272
if (getTransactionSynchronization() == SYNCHRONIZATION_NEVER) {
73-
throw new IllegalStateException("Transaction synchronization is needed always");
73+
throw new IllegalStateException("Transaction synchronization must not be disabled");
7474
}
7575
}
7676

@@ -81,7 +81,7 @@ public void afterPropertiesSet() {
8181
protected ArangoTransactionObject doGetTransaction() {
8282
ArangoTransactionHolder holder = (ArangoTransactionHolder) TransactionSynchronizationManager.getResource(this);
8383
try {
84-
return new ArangoTransactionObject(operations.db(), getDefaultTimeout(), holder);
84+
return new ArangoTransactionObject(operations.db(), CollectionCallback.fromOperations(operations), getDefaultTimeout(), holder);
8585
} catch (ArangoDBException error) {
8686
throw new TransactionSystemException("Cannot create transaction object", error);
8787
}

src/main/java/com/arangodb/springframework/transaction/ArangoTransactionObject.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.arangodb.ArangoDatabase;
2525
import com.arangodb.entity.StreamTransactionStatus;
2626
import com.arangodb.model.StreamTransactionOptions;
27+
import com.arangodb.springframework.core.template.CollectionCallback;
2728
import org.apache.commons.logging.Log;
2829
import org.apache.commons.logging.LogFactory;
2930
import org.springframework.lang.Nullable;
@@ -46,11 +47,13 @@ class ArangoTransactionObject implements SmartTransactionObject {
4647
private static final Log logger = LogFactory.getLog(ArangoTransactionObject.class);
4748

4849
private final ArangoDatabase database;
50+
private final CollectionCallback collectionCallback;
4951
private final ArangoTransactionHolder holder;
5052
private int timeout;
5153

52-
ArangoTransactionObject(ArangoDatabase database, int defaultTimeout, @Nullable ArangoTransactionHolder holder) {
54+
ArangoTransactionObject(ArangoDatabase database, CollectionCallback collectionCallback, int defaultTimeout, @Nullable ArangoTransactionHolder holder) {
5355
this.database = database;
56+
this.collectionCallback = collectionCallback;
5457
this.holder = holder == null ? new ArangoTransactionHolder() : holder;
5558
this.timeout = defaultTimeout;
5659
}
@@ -71,6 +74,7 @@ void configure(TransactionDefinition definition) {
7174
ArangoTransactionHolder getOrBegin(Collection<String> collections) throws ArangoDBException {
7275
addCollections(collections);
7376
if (holder.getStreamTransactionId() == null) {
77+
holder.getCollectionNames().forEach(collectionCallback::collection);
7478
StreamTransactionOptions options = new StreamTransactionOptions()
7579
.allowImplicit(true)
7680
.writeCollections(holder.getCollectionNames().toArray(new String[0]))

src/test/java/com/arangodb/springframework/testdata/Actor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import java.util.List;
2424

25+
import com.arangodb.springframework.annotation.PersistentIndex;
2526
import org.springframework.data.annotation.Id;
2627

2728
import com.arangodb.springframework.annotation.Document;
@@ -33,6 +34,7 @@
3334
* @author Christian Lechner
3435
*/
3536
@Document("actors")
37+
@PersistentIndex(fields = "name")
3638
public class Actor {
3739

3840
@Id

src/test/java/com/arangodb/springframework/transaction/ArangoTransactionManagerRepositoryTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.arangodb.springframework.ArangoTransactionalTestConfiguration;
55
import com.arangodb.springframework.repository.ActorRepository;
66
import com.arangodb.springframework.repository.MovieRepository;
7-
import com.arangodb.springframework.testdata.Actor;
87
import com.arangodb.springframework.testdata.Movie;
98
import org.junit.Test;
109
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,7 +17,7 @@
1817
public class ArangoTransactionManagerRepositoryTest extends AbstractArangoTest {
1918

2019
public ArangoTransactionManagerRepositoryTest() {
21-
super(Movie.class, Actor.class);
20+
super(Movie.class);
2221
}
2322

2423
@Autowired
@@ -66,4 +65,10 @@ public void shouldRollbackWithinTransaction() {
6665

6766
assertThat(movieRepository.findById(starWars.getId())).isNotPresent();
6867
}
68+
69+
@Test
70+
@Transactional(label = "actors")
71+
public void shouldCreateCollectionsBeforeTransaction() {
72+
actorRepository.findAll();
73+
}
6974
}

src/test/java/com/arangodb/springframework/transaction/ArangoTransactionManagerTest.java

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.arangodb.springframework.transaction;
22

3-
import com.arangodb.ArangoDB;
43
import com.arangodb.ArangoDatabase;
5-
import com.arangodb.DbName;
64
import com.arangodb.entity.StreamTransactionEntity;
75
import com.arangodb.entity.StreamTransactionStatus;
86
import com.arangodb.model.StreamTransactionOptions;
@@ -72,7 +70,7 @@ public void cleanupSync() {
7270

7371
@Test
7472
public void getTransactionReturnsNewTransactionWithoutStreamTransaction() {
75-
TransactionStatus status = underTest.getTransaction(new DefaultTransactionAttribute());
73+
TransactionStatus status = underTest.getTransaction(createTransactionAttribute("test"));
7674
assertThat(status.isNewTransaction(), is(true));
7775
verify(bridge).setCurrentTransaction(any());
7876
ArangoTransactionHolder resource = (ArangoTransactionHolder) TransactionSynchronizationManager.getResource(underTest);
@@ -84,12 +82,8 @@ public void getTransactionReturnsNewTransactionWithoutStreamTransaction() {
8482

8583
@Test
8684
public void innerGetTransactionIsNotNewTransactionIncludingFormerCollections() {
87-
DefaultTransactionAttribute first = new DefaultTransactionAttribute();
88-
first.setLabels(Collections.singleton("foo"));
89-
TransactionStatus outer = underTest.getTransaction(first);
90-
DefaultTransactionAttribute second = new DefaultTransactionAttribute();
91-
second.setLabels(Collections.singleton("bar"));
92-
TransactionStatus inner = underTest.getTransaction(second);
85+
TransactionStatus outer = underTest.getTransaction(createTransactionAttribute("outer", "foo"));
86+
TransactionStatus inner = underTest.getTransaction(createTransactionAttribute("inner", "bar"));
9387
assertThat(inner.isNewTransaction(), is(false));
9488
ArangoTransactionObject transactionObject = getTransactionObject(inner);
9589
assertThat(transactionObject.getHolder().getCollectionNames(), hasItems("foo", "bar"));
@@ -98,8 +92,8 @@ public void innerGetTransactionIsNotNewTransactionIncludingFormerCollections() {
9892

9993
@Test(expected = UnexpectedRollbackException.class)
10094
public void innerRollbackCausesUnexpectedRollbackOnOuterCommit() {
101-
TransactionStatus outer = underTest.getTransaction(new DefaultTransactionAttribute());
102-
TransactionStatus inner = underTest.getTransaction(new DefaultTransactionAttribute());
95+
TransactionStatus outer = underTest.getTransaction(createTransactionAttribute("outer"));
96+
TransactionStatus inner = underTest.getTransaction(createTransactionAttribute("inner"));
10397
underTest.rollback(inner);
10498
try {
10599
underTest.commit(outer);
@@ -110,8 +104,7 @@ public void innerRollbackCausesUnexpectedRollbackOnOuterCommit() {
110104

111105
@Test
112106
public void getTransactionReturnsTransactionCreatesStreamTransactionWithAllCollectionsOnBridgeBeginCall() {
113-
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
114-
definition.setLabels(Collections.singleton("baz"));
107+
DefaultTransactionAttribute definition = createTransactionAttribute("timeout", "baz");
115108
definition.setTimeout(20);
116109
TransactionStatus status = underTest.getTransaction(definition);
117110
beginTransaction("123", "foo", "bar");
@@ -127,17 +120,14 @@ public void getTransactionReturnsTransactionCreatesStreamTransactionWithAllColle
127120

128121
@Test
129122
public void nestedGetTransactionReturnsExistingTransactionWithFormerCollections() {
130-
DefaultTransactionAttribute first = new DefaultTransactionAttribute();
131-
first.setLabels(Collections.singleton("foo"));
132-
TransactionStatus outer = underTest.getTransaction(first);
123+
TransactionStatus outer = underTest.getTransaction(createTransactionAttribute("outer", "foo"));
133124
assertThat(outer.isNewTransaction(), is(true));
134125

135126
beginTransaction("123", "foo", "bar");
136127
when(streamTransaction.getStatus())
137128
.thenReturn(StreamTransactionStatus.running);
138129

139-
DefaultTransactionAttribute second = new DefaultTransactionAttribute();
140-
second.setLabels(Collections.singleton("bar"));
130+
DefaultTransactionAttribute second = createTransactionAttribute("inner", "bar");
141131
TransactionStatus inner1 = underTest.getTransaction(second);
142132
assertThat(inner1.isNewTransaction(), is(false));
143133
ArangoTransactionObject tx1 = getTransactionObject(inner1);
@@ -155,9 +145,8 @@ public void nestedGetTransactionReturnsExistingTransactionWithFormerCollections(
155145

156146
@Test
157147
public void getTransactionForPropagationSupportsWithoutExistingCreatesDummyTransaction() {
158-
DefaultTransactionAttribute supports = new DefaultTransactionAttribute();
148+
DefaultTransactionAttribute supports = createTransactionAttribute("test", "foo");
159149
supports.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
160-
supports.setLabels(Collections.singleton("foo"));
161150
TransactionStatus empty = underTest.getTransaction(supports);
162151
assertThat(empty.isNewTransaction(), is(false));
163152
underTest.commit(empty);
@@ -167,12 +156,9 @@ public void getTransactionForPropagationSupportsWithoutExistingCreatesDummyTrans
167156

168157
@Test
169158
public void getTransactionForPropagationSupportsWithExistingCreatesInner() {
170-
DefaultTransactionAttribute first = new DefaultTransactionAttribute();
171-
first.setLabels(Collections.singleton("foo"));
172-
TransactionStatus outer = underTest.getTransaction(first);
173-
DefaultTransactionAttribute supports = new DefaultTransactionAttribute();
159+
TransactionStatus outer = underTest.getTransaction(createTransactionAttribute("outer", "foo"));
160+
DefaultTransactionAttribute supports = createTransactionAttribute("supports", "bar");
174161
supports.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
175-
supports.setLabels(Collections.singleton("bar"));
176162
TransactionStatus inner = underTest.getTransaction(supports);
177163
assertThat(inner.isNewTransaction(), is(false));
178164
underTest.commit(inner);
@@ -183,10 +169,7 @@ public void getTransactionForPropagationSupportsWithExistingCreatesInner() {
183169

184170
@Test
185171
public void getTransactionWithMultipleBridgeCallsWorksForKnownCollections() {
186-
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
187-
definition.setLabels(Collections.singleton("baz"));
188-
definition.setTimeout(20);
189-
underTest.getTransaction(definition);
172+
underTest.getTransaction(createTransactionAttribute("test", "baz"));
190173
beginTransaction("123", "foo");
191174
beginPassed.getValue().apply(Arrays.asList("foo", "baz"));
192175
verify(database).beginStreamTransaction(optionsPassed.capture());
@@ -196,10 +179,7 @@ public void getTransactionWithMultipleBridgeCallsWorksForKnownCollections() {
196179

197180
@Test
198181
public void getTransactionWithMultipleBridgeCallsIgnoresAdditionalCollections() {
199-
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
200-
definition.setLabels(Collections.singleton("bar"));
201-
definition.setTimeout(20);
202-
TransactionStatus state = underTest.getTransaction(definition);
182+
TransactionStatus state = underTest.getTransaction(createTransactionAttribute("test", "bar"));
203183
beginTransaction("123", "foo");
204184
beginPassed.getValue().apply(Collections.singletonList("baz"));
205185
assertThat(getTransactionObject(state).getHolder().getCollectionNames(), hasItems("foo", "bar"));
@@ -208,7 +188,7 @@ public void getTransactionWithMultipleBridgeCallsIgnoresAdditionalCollections()
208188

209189
@Test(expected = InvalidIsolationLevelException.class)
210190
public void getTransactionThrowsInvalidIsolationLevelExceptionForIsolationSerializable() {
211-
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
191+
DefaultTransactionAttribute definition = createTransactionAttribute("serializable");
212192
definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
213193
underTest.getTransaction(definition);
214194
}
@@ -235,4 +215,11 @@ private ArangoTransactionObject getTransactionObject(TransactionStatus status) {
235215
private TransactionCollectionOptions getCollections(StreamTransactionOptions options) {
236216
return (TransactionCollectionOptions) forDirectFieldAccess(options).getPropertyValue("collections");
237217
}
218+
219+
private static DefaultTransactionAttribute createTransactionAttribute(String name, String... collections) {
220+
DefaultTransactionAttribute transactionAttribute = new DefaultTransactionAttribute();
221+
transactionAttribute.setName(name);
222+
transactionAttribute.setLabels(Arrays.asList(collections));
223+
return transactionAttribute;
224+
}
238225
}

src/test/resources/logback-test.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
</encoder>
99
</appender>
1010

11-
<root level="info">
11+
<root level="warn">
1212
<appender-ref ref="STDOUT" />
1313
</root>
14+
<logger name="com.arangodb.springframework" level="debug" />
1415

1516
<!-- <logger name="com.arangodb.internal.velocystream.internal.MessageStore" level="debug" />-->
1617
<!-- <logger name="com.arangodb.internal.velocystream.VstCommunicationSync" level="debug" />-->

0 commit comments

Comments
 (0)