1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.proxy.backend.handler.transaction;
19
20 import lombok.RequiredArgsConstructor;
21 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
22 import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
23 import org.apache.shardingsphere.infra.hint.HintValueContext;
24 import org.apache.shardingsphere.infra.session.query.QueryContext;
25 import org.apache.shardingsphere.proxy.backend.connector.DatabaseConnector;
26 import org.apache.shardingsphere.proxy.backend.connector.DatabaseConnectorFactory;
27 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
28 import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseRow;
29 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
30 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
31 import org.apache.shardingsphere.proxy.backend.util.TransactionUtils;
32 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XABeginStatement;
33 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XACommitStatement;
34 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARecoveryStatement;
35 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARollbackStatement;
36 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAStatement;
37 import org.apache.shardingsphere.transaction.api.TransactionType;
38 import org.apache.shardingsphere.transaction.xa.jta.exception.XATransactionNestedBeginException;
39
40 import java.sql.SQLException;
41 import java.util.Collections;
42
43
44
45
46
47 @RequiredArgsConstructor
48 public final class TransactionXAHandler implements ProxyBackendHandler {
49
50 private final XAStatement xaStatement;
51
52 private final ConnectionSession connectionSession;
53
54 private final DatabaseConnector backendHandler;
55
56 public TransactionXAHandler(final SQLStatementContext sqlStatementContext, final String sql, final ConnectionSession connectionSession) {
57 xaStatement = (XAStatement) sqlStatementContext.getSqlStatement();
58 this.connectionSession = connectionSession;
59 backendHandler = DatabaseConnectorFactory.getInstance().newInstance(
60 new QueryContext(sqlStatementContext, sql, Collections.emptyList(), new HintValueContext()), connectionSession.getDatabaseConnectionManager(), false);
61 }
62
63 @Override
64 public boolean next() throws SQLException {
65 return xaStatement instanceof XARecoveryStatement && backendHandler.next();
66 }
67
68 @Override
69 public QueryResponseRow getRowData() throws SQLException {
70 return xaStatement instanceof XARecoveryStatement ? backendHandler.getRowData() : new QueryResponseRow(Collections.emptyList());
71 }
72
73 @Override
74 public ResponseHeader execute() throws SQLException {
75 if (xaStatement instanceof XABeginStatement) {
76 return begin();
77 }
78 if (xaStatement instanceof XACommitStatement || xaStatement instanceof XARollbackStatement) {
79 return finish();
80 }
81 return backendHandler.execute();
82 }
83
84
85
86
87 private ResponseHeader begin() throws SQLException {
88 ShardingSpherePreconditions.checkState(!connectionSession.getTransactionStatus().isInTransaction(), XATransactionNestedBeginException::new);
89 ResponseHeader result = backendHandler.execute();
90 TransactionType transactionType = TransactionUtils.getTransactionType(connectionSession.getConnectionContext().getTransactionContext());
91 connectionSession.getConnectionContext().getTransactionContext().beginTransaction(String.valueOf(transactionType));
92 return result;
93 }
94
95 private ResponseHeader finish() throws SQLException {
96 try {
97 return backendHandler.execute();
98 } finally {
99 connectionSession.getConnectionContext().clearTransactionContext();
100 connectionSession.getConnectionContext().clearCursorContext();
101 }
102 }
103 }