https://github.com/cockroachdb/cockroach-transaction-demo
Demonstrate best practices in using transactions in a Spring Boot application
https://github.com/cockroachdb/cockroach-transaction-demo
Last synced: 12 months ago
JSON representation
Demonstrate best practices in using transactions in a Spring Boot application
- Host: GitHub
- URL: https://github.com/cockroachdb/cockroach-transaction-demo
- Owner: cockroachdb
- Created: 2024-05-15T17:58:16.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-03T14:31:59.000Z (about 2 years ago)
- Last Synced: 2025-06-13T14:02:30.690Z (about 1 year ago)
- Language: Java
- Homepage:
- Size: 239 KB
- Stars: 0
- Watchers: 48
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
Awesome Lists containing this project
README
== CockroachDB Transaction Best Practices
This repository contains a sample application that illustrates some best practices regarding transaction handling with CockroachDB.
The project included uses Spring Boot + Spring Data JPA.
BTW, if you're new to CockroachDB and how it works, be sure to check out https://thesecretlivesofdata.com/raft/[The Raft protocol], the mechanism Cockroach uses to seamlessly replicate and manage your data in a truly distributed fashion.
=== Database Schema + Sample Data
[source,sql]
----
-- drop tables
DROP TABLE IF EXISTS items;
-- re-create tables
CREATE TABLE items (item_id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
name STRING,
description STRING,
price DECIMAL NOT NULL,
quantity INT DEFAULT 0);
INSERT INTO items (name, description, quantity, price) VALUES ('foo', 'fang', 200, 0.0);
----
=== JPA Structure
The following Java class shows the JPA structure used in the app:
[source,java]
----
@Entity
@Table(name = "items")
class Item {
@Id
@GeneratedValue(strategy = GenerationType.UUID) //
private UUID itemId;
private String name;
private String description;
private int quantity;
private double price;
...
}
----
To see the rest of the project, feel free to clone this repository and open it up inside your favorite IDE.
=== Read Committed Transaction
The following diagram illustrates a simple scenario that involves *read committed* transactions, and what can happen when you have competing transactions.
image::01-read-committed-competing-transaction.png[Read Committed Flow]
See link:READ_COMMITTED.md[]
=== Serializable Transaction
The following diagram illustrates a simple scenario that involves *serializable* transactions, and how competing transactions can translate into an exception, which can be handled.
image::02-serializable-competing-transaction.png[Serializable Flow]
See link:SERIALIZABLE.md[]
=== SELECT FOR UPDATE scenario
`SELECT FOR UPDATE` provides the means to reduce retry errors from occurring.
image::04-sql-for-update.png[SELECT FOR UPDATE scenario]
See link:SELECT_FOR_UPDATE.adoc[]
=== To run this application
For this app to work, you must:
. Type `cockroach start-single-node --insecure` to launch CockroachDB.
. In another shell, type `cockroach sql --insecure` to creation a SQL session.
. Type `drop database if exists kwikshoppr cascade; create database kwikshoppr;` to create the database for this app.
. In the SQL session, type `create database kwikshoppr;` to create the database for this app.
. In the SQL session, type `SET CLUSTER SETTING sql.txn.read_committed_isolation.enabled = 'true';` to enable READ_COMMITTED transactions.
If you need to restart, type `drop database if exists kwikshoppr cascade;` in the SQL session and then create the database again.
You can NOT run the application without the database existing, because the name of the database (`kwikshoppr`) is embedded inside `application.properties` as part of the JDBC connection string.