Skip to content

Commit

Permalink
refactoring transaction repository
Browse files Browse the repository at this point in the history
Add CachableJdbcTransactionRepository and
SimpleJdbcTransactionRepository. Default use
CachableJdbcTransactionRepository
  • Loading branch information
changmingxie committed Jan 11, 2016
1 parent a1ab806 commit 1926ca8
Show file tree
Hide file tree
Showing 13 changed files with 620 additions and 59 deletions.
25 changes: 0 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +0,0 @@
# tcc-transaction
tcc-transaction是TCC型事务java实现

Try: 尝试执行业务

完成所有业务检查(一致性)

预留必须业务资源(准隔离性)

Confirm: 确认执行业务

真正执行业务

不作任何业务检查

只使用Try阶段预留的业务资源

Confirm操作满足幂等性

Cancel: 取消执行业务

释放Try阶段预留的业务资源

Cancel操作满足幂等性

20 changes: 10 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>org.mengyun</groupId>
<artifactId>tcc-transaction</artifactId>
<packaging>pom</packaging>
<version>1.0.4</version>
<version>1.0.6</version>
<modules>
<module>tcc-transaction-core</module>
<module>tcc-transaction-api</module>
Expand All @@ -21,17 +21,12 @@
<java.src.version>1.6</java.src.version>
<java.target.version>1.6</java.target.version>
<project.encoding>UTF-8</project.encoding>
<!--<repo.internal.snapshots.url>http://repo1.maven.org/maven2-->
<!--</repo.internal.snapshots.url>-->
<!--<repo.internal.releases.url>http://repo1.maven.org/maven2-->
<!--</repo.internal.releases.url>-->
<!--<repo.proxy.url>http://repo1.maven.org/maven2</repo.proxy.url>-->

<repo.internal.snapshots.url>http://artifactory.ximalaya.com/artifactory/thirdparty-snapshots-local/
<repo.internal.snapshots.url>http://repo1.maven.org/maven2
</repo.internal.snapshots.url>
<repo.internal.releases.url>http://artifactory.ximalaya.com/artifactory/thirdparty-releases-local/
<repo.internal.releases.url>http://repo1.maven.org/maven2
</repo.internal.releases.url>
<repo.proxy.url>http://repo1.maven.org/maven2 http://repo1.maven.org/maven2</repo.proxy.url>
<repo.proxy.url>http://repo1.maven.org/maven2</repo.proxy.url>


<repo.external.url>http://repo1.maven.org/maven2</repo.external.url>

Expand All @@ -52,6 +47,11 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
Expand Down
2 changes: 1 addition & 1 deletion tcc-transaction-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>tcc-transaction</artifactId>
<groupId>org.mengyun</groupId>
<version>1.0.4</version>
<version>1.0.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
public class TransactionContext implements Serializable {

private static final long serialVersionUID = -8199390103169700387L;
private TransactionXid xid;

private int status;
Expand Down
2 changes: 1 addition & 1 deletion tcc-transaction-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>tcc-transaction</artifactId>
<groupId>org.mengyun</groupId>
<version>1.0.4</version>
<version>1.0.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
7 changes: 6 additions & 1 deletion tcc-transaction-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>tcc-transaction</artifactId>
<groupId>org.mengyun</groupId>
<version>1.0.4</version>
<version>1.0.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -49,6 +49,11 @@
<artifactId>log4j</artifactId>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package org.mengyun.tcctransaction.spring.repository;


import org.mengyun.tcctransaction.Transaction;
import org.mengyun.tcctransaction.TransactionRepository;
import org.mengyun.tcctransaction.api.TransactionXid;
import org.mengyun.tcctransaction.utils.SerializationUtils;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.util.CollectionUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
* Created by changmingxie on 10/30/15.
*/
public abstract class AbstractJdbcTransactionRepository extends JdbcDaoSupport implements TransactionRepository {

public AbstractJdbcTransactionRepository() {

}

protected abstract void putToCache(Transaction transaction);

protected abstract void removeFromCache(Transaction transaction);

protected abstract Transaction findFromCache(TransactionXid transactionXid);

protected abstract void putToErrorCache(Transaction transaction);

protected abstract void removeFromErrorCache(Transaction transaction);

protected abstract Collection<Transaction> findAllFromErrorCache();

@Override
public void create(Transaction transaction) {
doCreate(transaction);
putToCache(transaction);
}

@Override
public void update(Transaction transaction) {
doUpdate(transaction);
putToCache(transaction);
}

@Override
public void delete(Transaction transaction) {
doDelete(transaction);
removeFromCache(transaction);
}

@Override
public Transaction findByXid(TransactionXid transactionXid) {
Transaction transaction = findFromCache(transactionXid);

if (transaction == null) {
transaction = doFind(transactionXid);

if (transaction != null) {
putToCache(transaction);
}
}

return transaction;
}

@Override
public List<Transaction> findAll() {

List<Transaction> transactions = doFindAll(null);
for (Transaction transaction : transactions) {
putToCache(transaction);
}

return transactions;
}

@Override
public void addErrorTransaction(Transaction transaction) {
putToErrorCache(transaction);
}

@Override
public void removeErrorTransaction(Transaction transaction) {
removeFromErrorCache(transaction);
}

@Override
public Collection<Transaction> findAllErrorTransactions() {
return findAllFromErrorCache();
}

private void doCreate(Transaction transaction) {

Connection connection = null;
PreparedStatement stmt = null;

try {
connection = this.getConnection();

StringBuilder builder = new StringBuilder();
builder.append("INSERT INTO TCC_TRANSACTION " +
"(GLOBAL_TX_ID,BRANCH_QUALIFIER,TRANSACTION_TYPE,CONTENT,STATUS,RETRIED_COUNT)" +
"VALUES(?,?,?,?,?,0)");

stmt = connection.prepareStatement(builder.toString());

stmt.setBytes(1, transaction.getXid().getGlobalTransactionId());
stmt.setBytes(2, transaction.getXid().getBranchQualifier());

stmt.setInt(3, transaction.getTransactionType().getId());
stmt.setBytes(4, SerializationUtils.serialize(transaction));
stmt.setInt(5, transaction.getStatus().getId());

stmt.executeUpdate();

} catch (SQLException e) {
throw new Error(e);
} finally {
closeStatement(stmt);
this.releaseConnection(connection);
}
}

private void doUpdate(Transaction transaction) {
Connection connection = null;
PreparedStatement stmt = null;

try {
connection = this.getConnection();

StringBuilder builder = new StringBuilder();
builder.append("UPDATE TCC_TRANSACTION SET " +
"CONTENT = ?,STATUS = ?,RETRIED_COUNT = ? WHERE GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ?");

stmt = connection.prepareStatement(builder.toString());

stmt.setBytes(1, SerializationUtils.serialize(transaction));
stmt.setInt(2, transaction.getStatus().getId());
stmt.setInt(3, transaction.getRetriedCount());
stmt.setBytes(4, transaction.getXid().getGlobalTransactionId());
stmt.setBytes(5, transaction.getXid().getBranchQualifier());

stmt.executeUpdate();

} catch (Throwable e) {
throw new Error(e);
} finally {
closeStatement(stmt);
this.releaseConnection(connection);
}
}

public void doDelete(Transaction transaction) {
Connection connection = null;
PreparedStatement stmt = null;

try {
connection = this.getConnection();

StringBuilder builder = new StringBuilder();
builder.append("DELETE FROM TCC_TRANSACTION " +
" WHERE GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ?");

stmt = connection.prepareStatement(builder.toString());

stmt.setBytes(1, transaction.getXid().getGlobalTransactionId());
stmt.setBytes(2, transaction.getXid().getBranchQualifier());

stmt.executeUpdate();

} catch (SQLException e) {
throw new Error(e);
} finally {
closeStatement(stmt);
this.releaseConnection(connection);
}
}

private Transaction doFind(TransactionXid xid) {

List<TransactionXid> transactionXids = Arrays.asList(xid);

List<Transaction> transactions = doFindAll(transactionXids);

if (!CollectionUtils.isEmpty(transactions)) {
return transactions.get(0);
}
return null;
}

private List<Transaction> doFindAll(List<TransactionXid> xids) {

List<Transaction> transactions = new ArrayList<Transaction>();

Connection connection = null;
PreparedStatement stmt = null;

try {
connection = this.getConnection();

StringBuilder builder = new StringBuilder();
builder.append("SELECT GLOBAL_TX_ID, BRANCH_QUALIFIER, CONTENT,STATUS,TRANSACTION_TYPE,RETRIED_COUNT" +
" FROM TCC_TRANSACTION ");

if (!CollectionUtils.isEmpty(xids)) {
builder.append(" WHERE ");
for (TransactionXid xid : xids) {
builder.append("( GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ? )");
}
}

stmt = connection.prepareStatement(builder.toString());

if (!CollectionUtils.isEmpty(xids)) {

int i = 0;

for (TransactionXid xid : xids) {
stmt.setBytes(++i, xid.getGlobalTransactionId());
stmt.setBytes(++i, xid.getBranchQualifier());
}
}

ResultSet resultSet = stmt.executeQuery();

while (resultSet.next()) {

byte[] globalTxid = resultSet.getBytes(1);
byte[] branchQualifier = resultSet.getBytes(2);
byte[] transactionBytes = resultSet.getBytes(3);
int status = resultSet.getInt(4);
int transactionType = resultSet.getInt(5);
int retriedCount = resultSet.getInt(6);

Transaction transaction = (Transaction) SerializationUtils.deserialize(transactionBytes);
transaction.resetRetriedCount(retriedCount);

transactions.add(transaction);
}
} catch (Throwable e) {
throw new Error(e);
} finally {
closeStatement(stmt);
this.releaseConnection(connection);
}

return transactions;
}

private void closeStatement(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Loading

0 comments on commit 1926ca8

Please sign in to comment.