Skip to content

Commit 244f971

Browse files
mikereichemp911de
authored andcommitted
Add Couchbase Transactions Example.
Closes #650. Original pull request: #663
1 parent aa6fccc commit 244f971

File tree

12 files changed

+566
-0
lines changed

12 files changed

+566
-0
lines changed

couchbase/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<modules>
1919
<module>example</module>
2020
<module>reactive</module>
21+
<module>transactions</module>
2122
<module>util</module>
2223
</modules>
2324

couchbase/transactions/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Getting Started
2+
3+
### Running the Sample
4+
5+
* `$> docker run -d --name db -p 8091-8097:8091-8097 -p 11210:11210 -p 11207:11207 -p 18091-18095:18091-18095 -p 18096:18096 -p 18097:18097 couchbase`
6+
* Create new _cluster_ via `http://localhost:8091/`
7+
* Create new [bucket](http://localhost:8091/ui/index.html#/buckets) named _travel-sample_.
8+
*
9+
10+
### Reference Documentation
11+
For further reference, please consider the following sections:
12+
13+
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
14+
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.2/maven-plugin/reference/html/)
15+
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.2/maven-plugin/reference/html/#build-image)
16+
* [Spring Data Couchbase](https://docs.spring.io/spring-boot/docs/2.5.2/reference/htmlsingle/#boot-features-couchbase)
17+

couchbase/transactions/pom.xml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<artifactId>spring-data-couchbase-transactions</artifactId>
7+
<name>Spring Data Couchbase - Transaction example</name>
8+
<description>Transactions Demo project for Spring Data Couchbase</description>
9+
10+
<parent>
11+
<groupId>org.springframework.data.examples</groupId>
12+
<artifactId>spring-data-couchbase-examples</artifactId>
13+
<version>2.0.0.BUILD-SNAPSHOT</version>
14+
</parent>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.springframework.boot</groupId>
19+
<artifactId>spring-boot-starter-data-couchbase</artifactId>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-starter-test</artifactId>
25+
<scope>test</scope>
26+
</dependency>
27+
28+
<dependency>
29+
<groupId>${project.groupId}</groupId>
30+
<artifactId>spring-data-couchbase-example-utils</artifactId>
31+
<version>${project.version}</version>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.springframework.data.examples</groupId>
36+
<artifactId>spring-data-couchbase-example-utils</artifactId>
37+
<version>2.0.0.BUILD-SNAPSHOT</version>
38+
<scope>test</scope>
39+
</dependency>
40+
41+
</dependencies>
42+
43+
<build>
44+
<plugins>
45+
<plugin>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-maven-plugin</artifactId>
48+
</plugin>
49+
</plugins>
50+
</build>
51+
52+
<repositories>
53+
<repository>
54+
<id>spring-libs-snapshot</id>
55+
<url>https://repo.spring.io/libs-snapshot</url>
56+
</repository>
57+
<repository>
58+
<id>sonatype-snapshot</id>
59+
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
60+
<snapshots>
61+
<enabled>true</enabled>
62+
</snapshots>
63+
<releases>
64+
<enabled>false</enabled>
65+
</releases>
66+
</repository>
67+
</repositories>
68+
69+
<pluginRepositories>
70+
<pluginRepository>
71+
<id>spring-snapshots</id>
72+
<url>https://repo.spring.io/snapshot</url>
73+
</pluginRepository>
74+
<pluginRepository>
75+
<id>spring-milestones</id>
76+
<url>https://repo.spring.io/milestone</url>
77+
</pluginRepository>
78+
</pluginRepositories>
79+
80+
</project>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.example.demo;
17+
18+
import org.springframework.data.annotation.Id;
19+
import org.springframework.data.annotation.PersistenceConstructor;
20+
import org.springframework.data.annotation.Version;
21+
import org.springframework.data.couchbase.core.index.QueryIndexed;
22+
import org.springframework.data.couchbase.core.mapping.Document;
23+
24+
/**
25+
* @author Michael Reiche
26+
*/
27+
@Document
28+
public class AirlineGates {
29+
@Id String id;
30+
@Version Long version;
31+
@QueryIndexed String name;
32+
String iata;
33+
Long gates;
34+
35+
@PersistenceConstructor
36+
public AirlineGates(String id, String name, String iata, Long gates) {
37+
this.id = id;
38+
this.name = name;
39+
this.iata = iata;
40+
this.gates = gates;
41+
}
42+
43+
public String getId() {
44+
return id;
45+
}
46+
public Long getGates() {
47+
return gates;
48+
}
49+
50+
public String toString(){
51+
StringBuffer sb=new StringBuffer();
52+
sb.append("{");
53+
sb.append("\"id\":"+id);
54+
sb.append(", \"name\":"+name);
55+
sb.append(", \"iata\":"+iata);
56+
sb.append(", \"gates\":"+gates);
57+
sb.append("}");
58+
59+
return sb.toString();
60+
}
61+
62+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2017-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.demo;
18+
19+
import org.springframework.data.couchbase.repository.CouchbaseRepository;
20+
import org.springframework.data.couchbase.repository.DynamicProxyable;
21+
import org.springframework.stereotype.Repository;
22+
23+
/**
24+
* @author Michael Reiche
25+
*/
26+
@Repository
27+
public interface AirlineGatesRepository
28+
extends CouchbaseRepository<AirlineGates, String>, DynamicProxyable<AirlineGatesRepository> {
29+
30+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2022 the original author or authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.example.demo;
17+
18+
import reactor.core.publisher.Mono;
19+
20+
import org.springframework.data.couchbase.core.CouchbaseTemplate;
21+
import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate;
22+
import org.springframework.data.couchbase.core.TransactionalSupport;
23+
import org.springframework.stereotype.Service;
24+
import org.springframework.transaction.annotation.Transactional;
25+
26+
/**
27+
* @author Michael Reiche
28+
*/
29+
@Service
30+
public class AirlineGatesService {
31+
CouchbaseTemplate template;
32+
ReactiveCouchbaseTemplate reactiveTemplate;
33+
AirlineGatesRepository airlineGatesRepository;
34+
35+
public AirlineGatesService(CouchbaseTemplate template, AirlineGatesRepository airlineGatesRepository) {
36+
this.template = template;
37+
this.reactiveTemplate = template.reactive();
38+
this.airlineGatesRepository = airlineGatesRepository;
39+
}
40+
41+
@Transactional
42+
public void transferGates(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) {
43+
AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId);
44+
AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId);
45+
toAirlineGates.gates += gatesToTransfer;
46+
fromAirlineGates.gates -= gatesToTransfer;
47+
template.save(fromAirlineGates);
48+
if (exceptionToThrow != null) {
49+
throw exceptionToThrow;
50+
}
51+
template.save(toAirlineGates);
52+
}
53+
54+
@Transactional
55+
public void transferGatesRepo(String fromId, String toId, int gatesToTransfer, RuntimeException exceptionToThrow) {
56+
AirlineGates fromAirlineGates = airlineGatesRepository.findById(fromId).orElse(null);
57+
AirlineGates toAirlineGates = airlineGatesRepository.findById(toId).orElse(null);
58+
toAirlineGates.gates += gatesToTransfer;
59+
fromAirlineGates.gates -= gatesToTransfer;
60+
airlineGatesRepository.save(fromAirlineGates);
61+
if (exceptionToThrow != null) {
62+
throw exceptionToThrow;
63+
}
64+
airlineGatesRepository.save(toAirlineGates);
65+
}
66+
67+
// The @Transactional annotation results in the method of the proxy for the service executing this in a transaction
68+
@Transactional
69+
public Mono<Void> transferGatesReactive(String fromId, String toId, int gatesToTransfer,
70+
RuntimeException exceptionToThrow) {
71+
return Mono.deferContextual(ctx -> {
72+
AirlineGates fromAirlineGates = template.findById(AirlineGates.class).one(fromId);
73+
AirlineGates toAirlineGates = template.findById(AirlineGates.class).one(toId);
74+
toAirlineGates.gates += gatesToTransfer;
75+
fromAirlineGates.gates -= gatesToTransfer;
76+
template.save(fromAirlineGates);
77+
if (exceptionToThrow != null) {
78+
throw exceptionToThrow;
79+
}
80+
return reactiveTemplate.save(toAirlineGates).then();
81+
});
82+
}
83+
84+
// This does not have the @Transactional annotation therefore is not executed in a transaction
85+
public AirlineGates save(AirlineGates airlineGates) {
86+
return template.save(airlineGates);
87+
}
88+
89+
// This does not have the @Transactional annotation therefore is not executed in a transaction
90+
public AirlineGates findById(String id) {
91+
return template.findById(AirlineGates.class).one(id);
92+
}
93+
94+
// This does not have the @Transactional annotation therefore is not executed in a transaction
95+
public AirlineGates saveRepo(AirlineGates airlineGates) {
96+
return airlineGatesRepository.save(airlineGates);
97+
}
98+
99+
// This does not have the @Transactional annotation therefore is not executed in a transaction
100+
public AirlineGates findByIdRepo(String id) {
101+
return airlineGatesRepository.findById(id).orElse(null);
102+
}
103+
}

0 commit comments

Comments
 (0)