Created
May 1, 2023 04:41
-
-
Save xialeistudio/fec5cbf1bf31ba235139af792653dc4c to your computer and use it in GitHub Desktop.
atomikos distributed transaction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.jta; | |
import com.atomikos.icatch.jta.UserTransactionImp; | |
import com.atomikos.icatch.jta.UserTransactionManager; | |
import com.atomikos.jdbc.AtomikosDataSourceBean; | |
import com.mysql.cj.jdbc.MysqlXADataSource; | |
import java.sql.Connection; | |
import java.sql.PreparedStatement; | |
import java.sql.ResultSet; | |
import java.sql.SQLException; | |
import java.util.Properties; | |
import javax.transaction.HeuristicMixedException; | |
import javax.transaction.HeuristicRollbackException; | |
import javax.transaction.NotSupportedException; | |
import javax.transaction.RollbackException; | |
import javax.transaction.SystemException; | |
import javax.transaction.UserTransaction; | |
public class Main { | |
public static void main(String[] args) { | |
UserTransactionManager utm = new UserTransactionManager(); | |
utm.setForceShutdown(false); | |
UserTransaction userTransaction = new UserTransactionImp(); | |
String databaseURL = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC"; | |
// order | |
MysqlXADataSource orderXADatasource = new MysqlXADataSource(); | |
orderXADatasource.setURL(databaseURL); | |
orderXADatasource.setUser("root"); | |
orderXADatasource.setPassword("root"); | |
AtomikosDataSourceBean orderDatasource = new AtomikosDataSourceBean(); | |
orderDatasource.setXaDataSource(orderXADatasource); | |
orderDatasource.setUniqueResourceName("order"); | |
orderDatasource.setTestQuery("SELECT 1"); | |
// product | |
MysqlXADataSource productXADatasource = new MysqlXADataSource(); | |
productXADatasource.setURL(databaseURL); | |
productXADatasource.setUser("root"); | |
productXADatasource.setPassword("root"); | |
AtomikosDataSourceBean productDatasource = new AtomikosDataSourceBean(); | |
productDatasource.setXaDataSource(productXADatasource); | |
productDatasource.setUniqueResourceName("product"); | |
productDatasource.setTestQuery("SELECT 1"); | |
// start transaction | |
try { | |
userTransaction.begin(); | |
try (Connection orderConn = orderDatasource.getConnection(); | |
Connection productConn = productDatasource.getConnection(); | |
PreparedStatement stmt1 = productConn.prepareStatement("SELECT * FROM products WHERE id=? FOR UPDATE ")) { | |
stmt1.setInt(1, 1); | |
// query product | |
try (ResultSet rs = stmt1.executeQuery()) { | |
if (!rs.next()) { | |
throw new SQLException("query failed"); | |
} | |
// reduce stock | |
try (PreparedStatement stmt3 = productConn.prepareStatement("UPDATE products SET stock=? WHERE id=?")) { | |
int stock = rs.getInt("stock") - 1; | |
stmt3.setInt(1, stock); | |
stmt3.setLong(2, 1); | |
if (stmt3.executeUpdate() == 0) { | |
throw new SQLException("update stock failed"); | |
} | |
System.out.printf("reduce stock succeed, current stock %d\n", stock); | |
// insert order | |
try (PreparedStatement stmt2 = orderConn.prepareStatement( | |
"INSERT INTO orders (id, user_id, product_id, amount, status, created_at, updated_at) VALUES (NULL,?,?,?,?,NOW(),NOW())")) { | |
stmt2.setInt(1, 1); | |
stmt2.setInt(2, 1); | |
stmt2.setInt(3, 1); | |
stmt2.setByte(4, (byte) 0); | |
if (stmt2.executeUpdate() == 0) { | |
throw new SQLException("insert product failed"); | |
} | |
System.out.print("insert product succeed\n"); | |
} | |
} | |
} | |
try { | |
userTransaction.commit(); | |
} catch (RollbackException | HeuristicMixedException | HeuristicRollbackException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} catch (SQLException | NotSupportedException | SystemException e) { | |
try { | |
userTransaction.rollback(); | |
} catch (SystemException ex) { | |
throw new RuntimeException(ex); | |
} | |
throw new RuntimeException(e); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>org.example</groupId> | |
<artifactId>sharding-jdbc-example</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<properties> | |
<maven.compiler.source>17</maven.compiler.source> | |
<maven.compiler.target>1.8</maven.compiler.target> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>com.mysql</groupId> | |
<artifactId>mysql-connector-j</artifactId> | |
<version>8.0.32</version> | |
</dependency> | |
<dependency> | |
<groupId>com.atomikos</groupId> | |
<artifactId>transactions-jta</artifactId> | |
<version>6.0.0M2</version> | |
</dependency> | |
<dependency> | |
<groupId>com.atomikos</groupId> | |
<artifactId>transactions-jdbc</artifactId> | |
<version>6.0.0M2</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.transaction</groupId> | |
<artifactId>jta</artifactId> | |
<version>1.1</version> | |
</dependency> | |
</dependencies> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment