Skip to content

Commit 559fbf7

Browse files
committed
Revise TransactionTemplate API usage
Related to: spring-projects/spring-framework#35561 * Use `TransactionTemplate.executeWithoutResult()` instead of `execute(s -> return null)` * Fix `DefaultLockRepository` to not check for null result of the `TransactionTemplate.execute()` as Nullability covers that for us * Remove `NullAway` from the `PostgresSubscribableChannel.doPollAndDispatchMessage()` as `RetryTemplate` and `TransactionTemplate` Nullability are now aligned
1 parent 69b7487 commit 559fbf7

File tree

14 files changed

+101
-152
lines changed

14 files changed

+101
-152
lines changed

spring-integration-core/src/test/java/org/springframework/integration/config/xml/DelayerUsageTests.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ public void testDelayWithDefaultSchedulerAndTransactionSynchronization() {
7373
long start = System.currentTimeMillis();
7474

7575
new TransactionTemplate(new PseudoTransactionManager())
76-
.execute(status -> {
77-
inputA.send(new GenericMessage<>("Hello"));
78-
return null;
79-
});
76+
.executeWithoutResult(status -> inputA.send(new GenericMessage<>("Hello")));
8077

8178
assertThat(outputA.receive(10000)).isNotNull();
8279
assertThat(System.currentTimeMillis() - start).isCloseTo(1000, withinPercentage(25));

spring-integration-core/src/test/java/org/springframework/integration/endpoint/PseudoTransactionalMessageSourceTests.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public Message<String> receive() {
200200
public void testCommitWithManager() {
201201
final PollableChannel queueChannel = new QueueChannel();
202202
TransactionTemplate transactionTemplate = new TransactionTemplate(new PseudoTransactionManager());
203-
transactionTemplate.execute(status -> {
203+
transactionTemplate.executeWithoutResult(status -> {
204204
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
205205
ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor =
206206
new ExpressionEvaluatingTransactionSynchronizationProcessor();
@@ -231,7 +231,6 @@ public Message<String> receive() {
231231
});
232232

233233
doPoll(adapter);
234-
return null;
235234
});
236235
Message<?> beforeCommitMessage = queueChannel.receive(1000);
237236
assertThat(beforeCommitMessage).isNotNull();
@@ -246,7 +245,7 @@ public void testRollbackWithManager() {
246245
final PollableChannel queueChannel = new QueueChannel();
247246
TransactionTemplate transactionTemplate = new TransactionTemplate(new PseudoTransactionManager());
248247
try {
249-
transactionTemplate.execute(status -> {
248+
transactionTemplate.executeWithoutResult(status -> {
250249

251250
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
252251
ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor =
@@ -289,7 +288,7 @@ public Message<String> receive() {
289288
public void testRollbackWithManagerUsingStatus() {
290289
final PollableChannel queueChannel = new QueueChannel();
291290
TransactionTemplate transactionTemplate = new TransactionTemplate(new PseudoTransactionManager());
292-
transactionTemplate.execute(status -> {
291+
transactionTemplate.executeWithoutResult(status -> {
293292

294293
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
295294
ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor =
@@ -318,7 +317,6 @@ public Message<String> receive() {
318317

319318
doPoll(adapter);
320319
status.setRollbackOnly();
321-
return null;
322320
});
323321
Message<?> rollbackMessage = queueChannel.receive(1000);
324322
assertThat(rollbackMessage).isNotNull();

spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/channel/PostgresSubscribableChannel.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,15 @@ private Optional<?> pollAndDispatchMessage() {
218218
}
219219
}
220220

221-
@SuppressWarnings("NullAway")
222221
private Optional<?> doPollAndDispatchMessage() {
223222
this.hasHandlersLock.readLock().lock();
224223
try {
225224
if (this.hasHandlers) {
226225
TransactionTemplate transactionTemplateToUse = this.transactionTemplate;
227226
if (transactionTemplateToUse != null) {
228227
return executeWithRetry(() ->
229-
transactionTemplateToUse.execute(status -> pollMessage().map(this::dispatch)));
228+
transactionTemplateToUse.execute(status ->
229+
pollMessage().map(this::dispatch)));
230230
}
231231
else {
232232
return pollMessage()

spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/DefaultLockRepository.java

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.time.Duration;
2121
import java.time.LocalDateTime;
2222
import java.time.ZoneOffset;
23-
import java.util.Objects;
2423
import java.util.UUID;
2524
import java.util.concurrent.atomic.AtomicBoolean;
2625

@@ -399,45 +398,42 @@ public void close() {
399398

400399
@Override
401400
public boolean delete(String lock) {
402-
Integer result = this.defaultTransactionTemplate.execute(
403-
transactionStatus -> this.template.update(this.deleteQuery, this.region, lock, this.id));
404-
return Objects.requireNonNull(result) == 1;
401+
return this.defaultTransactionTemplate.<Boolean>execute(
402+
transactionStatus ->
403+
this.template.update(this.deleteQuery, this.region, lock, this.id) == 1);
405404
}
406405

407406
@Override
408407
@Deprecated(since = "7.0")
409408
public boolean acquire(String lock) {
410-
return this.acquire(lock, this.ttl);
409+
return acquire(lock, this.ttl);
411410
}
412411

413412
@Override
414413
public boolean acquire(String lock, Duration ttlDuration) {
415-
Boolean result =
416-
this.readCommittedTransactionTemplate.execute(
417-
transactionStatus -> {
418-
if (this.template.update(this.updateQuery, this.id, ttlEpochMillis(ttlDuration),
419-
this.region, lock, this.id, epochMillis()) > 0) {
420-
return true;
421-
}
422-
try {
423-
return this.template.update(this.insertQuery, this.region, lock, this.id,
424-
epochMillis(), ttlEpochMillis(ttlDuration)) > 0;
425-
}
426-
catch (DataIntegrityViolationException ex) {
427-
return false;
428-
}
429-
});
430-
return Boolean.TRUE.equals(result);
414+
return this.readCommittedTransactionTemplate.<Boolean>execute(
415+
transactionStatus -> {
416+
if (this.template.update(this.updateQuery, this.id, ttlEpochMillis(ttlDuration),
417+
this.region, lock, this.id, epochMillis()) > 0) {
418+
return true;
419+
}
420+
try {
421+
return this.template.update(this.insertQuery, this.region, lock, this.id,
422+
epochMillis(), ttlEpochMillis(ttlDuration)) > 0;
423+
}
424+
catch (DataIntegrityViolationException ex) {
425+
return false;
426+
}
427+
});
431428
}
432429

433430
@Override
434431
public boolean isAcquired(String lock) {
435-
final Boolean result = this.readOnlyTransactionTemplate.execute(
432+
return this.readOnlyTransactionTemplate.<Boolean>execute(
436433
transactionStatus ->
437434
Integer.valueOf(1).equals(
438435
this.template.queryForObject(this.countQuery,
439436
Integer.class, this.region, lock, this.id, epochMillis())));
440-
return Boolean.TRUE.equals(result);
441437
}
442438

443439
@Override
@@ -455,10 +451,9 @@ public boolean renew(String lock) {
455451

456452
@Override
457453
public boolean renew(String lock, Duration ttlDuration) {
458-
final Boolean result = this.defaultTransactionTemplate.execute(
454+
return this.defaultTransactionTemplate.<Boolean>execute(
459455
transactionStatus ->
460456
this.template.update(this.renewQuery, ttlEpochMillis(ttlDuration), this.region, lock, this.id) == 1);
461-
return Boolean.TRUE.equals(result);
462457
}
463458

464459
private Timestamp ttlEpochMillis(Duration ttl) {

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcPollingChannelAdapterParserTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,11 @@ public void testParameterSourceInboundChannelAdapter() {
151151
@Test
152152
public void testMaxRowsInboundChannelAdapter() {
153153
setUp("pollingWithMaxRowsJdbcInboundChannelAdapterTest.xml", getClass());
154-
new TransactionTemplate(transactionManager).execute(status -> {
154+
new TransactionTemplate(transactionManager).executeWithoutResult(status -> {
155155
jdbcTemplate.update("insert into item values(1,'',2)");
156156
jdbcTemplate.update("insert into item values(2,'',2)");
157157
jdbcTemplate.update("insert into item values(3,'',2)");
158158
jdbcTemplate.update("insert into item values(4,'',2)");
159-
return null;
160159
});
161160
int count = 0;
162161
while (count < 4) {

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreMultipleChannelTests.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
* This test was created to reproduce INT-2980.
5151
*
5252
* @author Gunnar Hillert
53+
* @author Artem Bilan
5354
*
5455
*/
5556
@SpringJUnitConfig
@@ -62,7 +63,7 @@ public class MySqlJdbcMessageStoreMultipleChannelTests implements MySqlContainer
6263

6364
private static final CountDownLatch countDownLatch2 = new CountDownLatch(1);
6465

65-
private static AtomicBoolean success = new AtomicBoolean(true);
66+
private static final AtomicBoolean success = new AtomicBoolean(true);
6667

6768
@Autowired
6869
@Qualifier("requestChannel")
@@ -87,21 +88,19 @@ public void beforeTest() {
8788

8889
@AfterEach
8990
public void afterTest() {
90-
new TransactionTemplate(this.transactionManager).execute(status -> {
91-
this.jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
92-
this.jdbcTemplate.update("delete from INT_MESSAGE");
93-
this.jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
94-
return null;
95-
});
91+
new TransactionTemplate(this.transactionManager)
92+
.executeWithoutResult(status -> {
93+
this.jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
94+
this.jdbcTemplate.update("delete from INT_MESSAGE");
95+
this.jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
96+
});
9697
}
9798

9899
@Test
99100
public void testSendAndActivateTransactionalSend() throws Exception {
100-
101-
new TransactionTemplate(this.transactionManager).execute(status -> {
102-
requestChannel.send(MessageBuilder.withPayload("Hello ").build());
103-
return null;
104-
});
101+
new TransactionTemplate(this.transactionManager)
102+
.executeWithoutResult(status ->
103+
requestChannel.send(MessageBuilder.withPayload("Hello ").build()));
105104

106105
assertThat(countDownLatch1.await(10000, TimeUnit.MILLISECONDS))
107106
.as("countDownLatch1 was " + countDownLatch1.getCount()).isTrue();
@@ -119,7 +118,7 @@ public Splitter() {
119118
}
120119

121120
public List<Object> duplicate(Message<?> message) {
122-
ArrayList<Object> res = new ArrayList<Object>();
121+
ArrayList<Object> res = new ArrayList<>();
123122
res.add(message);
124123
res.add(message);
125124
return res;

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreTests.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,16 @@ public void init() {
8484
@AfterEach
8585
public void afterTest() {
8686
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
87-
new TransactionTemplate(this.transactionManager).execute(status -> {
88-
final int deletedGroupToMessageRows = jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
89-
final int deletedMessages = jdbcTemplate.update("delete from INT_MESSAGE");
90-
final int deletedMessageGroups = jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
91-
92-
LOG.info(String.format("Cleaning Database - Deleted Messages: %s, " +
93-
"Deleted GroupToMessage Rows: %s, Deleted Message Groups: %s",
94-
deletedMessages, deletedGroupToMessageRows, deletedMessageGroups));
95-
return null;
96-
});
87+
new TransactionTemplate(this.transactionManager)
88+
.executeWithoutResult(status -> {
89+
final int deletedGroupToMessageRows = jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
90+
final int deletedMessages = jdbcTemplate.update("delete from INT_MESSAGE");
91+
final int deletedMessageGroups = jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
92+
93+
LOG.info(String.format("Cleaning Database - Deleted Messages: %s, " +
94+
"Deleted GroupToMessage Rows: %s, Deleted Message Groups: %s",
95+
deletedMessages, deletedGroupToMessageRows, deletedMessageGroups));
96+
});
9797
}
9898

9999
@Test

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/oracle/OracleJdbcMessageStoreTests.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,16 @@ public void init() {
8383
@AfterEach
8484
public void afterTest() {
8585
final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
86-
new TransactionTemplate(this.transactionManager).execute(status -> {
87-
final int deletedGroupToMessageRows = jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
88-
final int deletedMessages = jdbcTemplate.update("delete from INT_MESSAGE");
89-
final int deletedMessageGroups = jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
90-
91-
LOG.info(String.format("Cleaning Database - Deleted Messages: %s, " +
92-
"Deleted GroupToMessage Rows: %s, Deleted Message Groups: %s",
93-
deletedMessages, deletedGroupToMessageRows, deletedMessageGroups));
94-
return null;
95-
});
86+
new TransactionTemplate(this.transactionManager)
87+
.executeWithoutResult(status -> {
88+
final int deletedGroupToMessageRows = jdbcTemplate.update("delete from INT_GROUP_TO_MESSAGE");
89+
final int deletedMessages = jdbcTemplate.update("delete from INT_MESSAGE");
90+
final int deletedMessageGroups = jdbcTemplate.update("delete from INT_MESSAGE_GROUP");
91+
92+
LOG.info(String.format("Cleaning Database - Deleted Messages: %s, " +
93+
"Deleted GroupToMessage Rows: %s, Deleted Message Groups: %s",
94+
deletedMessages, deletedGroupToMessageRows, deletedMessageGroups));
95+
});
9696
}
9797

9898
@Test

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreChannelIntegrationTests.java

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -109,41 +109,42 @@ public void testSendAndActivateWithRollback() throws Exception {
109109
// After a rollback in the poller the message is still waiting to be delivered
110110
// but unless we use a transaction here there is a chance that the queue will
111111
// appear empty....
112-
new TransactionTemplate(transactionManager).execute(status -> {
112+
new TransactionTemplate(transactionManager)
113+
.executeWithoutResult(status -> {
113114

114-
synchronized (storeLock) {
115+
synchronized (storeLock) {
115116

116-
assertThat(input.getQueueSize()).isEqualTo(1);
117-
assertThat(input.receive(100L)).isNotNull();
117+
assertThat(input.getQueueSize()).isEqualTo(1);
118+
assertThat(input.receive(100L)).isNotNull();
118119

119-
}
120-
return null;
120+
}
121121

122-
});
122+
});
123123
}
124124

125125
@Test
126126
public void testTransactionalSendAndReceive() throws Exception {
127127

128-
boolean result = new TransactionTemplate(transactionManager).execute(status -> {
128+
boolean result = new TransactionTemplate(transactionManager)
129+
.execute(status -> {
129130

130-
synchronized (storeLock) {
131+
synchronized (storeLock) {
131132

132-
boolean result1 = input.send(new GenericMessage<>("foo"), 100L);
133-
// This will time out because the transaction has not committed yet
134-
try {
135-
Service.await(100);
136-
fail("Expected timeout");
137-
}
138-
catch (Exception e) {
139-
// expected
140-
}
133+
boolean result1 = input.send(new GenericMessage<>("foo"), 100L);
134+
// This will time out because the transaction has not committed yet
135+
try {
136+
Service.await(100);
137+
fail("Expected timeout");
138+
}
139+
catch (Exception e) {
140+
// expected
141+
}
141142

142-
return result1;
143+
return result1;
143144

144-
}
145+
}
145146

146-
});
147+
});
147148

148149
assertThat(result).as("Could not send message").isTrue();
149150

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreChannelOnePollerIntegrationTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,12 @@ public void testSameTransactionDifferentChannelSendAndReceive() throws Exception
136136
* With the storeLock: It doesn't deadlock as long as the lock is injected into the poller as well.
137137
*/
138138
new TransactionTemplate(this.transactionManager)
139-
.execute(status -> {
139+
.executeWithoutResult(status -> {
140140
synchronized (this.storeLock) {
141141

142142
try {
143143
stopWatch.start();
144144
this.durable.receive(100L);
145-
return null;
146145
}
147146
finally {
148147
stopWatch.stop();

0 commit comments

Comments
 (0)