{"id":10006040,"date":"2022-07-28T17:52:51","date_gmt":"2022-07-28T09:52:51","guid":{"rendered":"https:\/\/ityet.com\/?p=10006040"},"modified":"2022-07-28T17:52:51","modified_gmt":"2022-07-28T09:52:51","slug":"polardb-x-%e6%ba%90%e7%a0%81%e8%a7%a3%e8%af%bb%ef%bc%9a%e4%ba%8b%e5%8a%a1%e7%9a%84%e4%b8%80%e7%94%9f","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006040","title":{"rendered":"PolarDB-X \u6e90\u7801\u89e3\u8bfb\uff1a\u4e8b\u52a1\u7684\u4e00\u751f"},"content":{"rendered":"<p>\u7b80\u4ecb\uff1a\u00a0\u672c\u6587\u5c06\u4e3b\u8981\u89e3\u8bfb PolarDB-X \u4e2d\u4e8b\u52a1\u90e8\u5206\u7684\u76f8\u5173\u4ee3\u7801\uff0c\u7740\u91cd\u89e3\u8bfb\u4e8b\u52a1\u7684\u4e00\u751f\u5728\u8ba1\u7b97\u8282\u70b9\uff08CN\uff09\u4e2d\u7684\u5173\u952e\u4ee3\u7801\uff1a\u4ece\u5f00\u59cb\u3001\u6267\u884c\u3001\u5230\u6700\u540e\u63d0\u4ea4\u8fd9\u4e00\u6574\u4e2a\u751f\u547d\u5468\u671f\u3002\u6982\u8ff0\u672c\u6587\u5c06\u4e3b\u8981\u89e3\u8bfb PolarDB-X \u4e2d\u4e8b\u52a1\u90e8\u5206\u7684\u76f8\u5173\u4ee3\u7801\uff0c\u7740\u91cd\u89e3\u8bfb\u4e8b\u52a1\u7684\u4e00\u751f\u5728\u8ba1\u7b97\u8282\u70b9\uff08CN\uff09\u4e2d\u7684\u5173\u952e\u4ee3\u7801\uff1a\u4ece\u5f00\u59cb\u3001\u6267\u884c\u3001\u5230\u6700\u540e\u63d0\u4ea4\u8fd9\u4e00\u6574\u4e2a\u751f\u547d\u5468\u671f\u3002\u5728\u9605\u8bfb\u672c\u6587\u524d\uff0c\u5f3a\u70c8\u63a8\u8350\u5148\u9605\u8bfb\u4e0e PolarDB-X \u4e8b\u52a1\u7cfb\u7edf\u76f8\u5173\u7684\u6587\u7ae0\uff1aPolarDB-X \u5f3a\u4e00\u81f4\u5206\u5e03\u5f0f\u4e8b\u52a1\u539f\u7406PolarDB-X \u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u5b9e\u73b0\uff08\u4e00\uff09PolarDB-X \u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u5b9e\u73b0\uff08\u4e8c\uff09InnoDB CTS \u6269\u5c55PolarDB-X \u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u5b9e\u73b0\uff08\u56db\uff09\uff1a\u8de8\u5730\u57df\u4e8b\u52a1\u65e0\u5904\u4e0d\u5728\u7684 MySQL XA \u4e8b\u52a1\u4ee5\u53ca\u6b64\u524d\u53d1\u5e03\u7684\u00a0PolarDB-X SQL \u7684\u4e00\u751f\u4e8b\u52a1\u4e0e\u8fde\u63a5\u5728 PolarDB-X \u7684 CN \u5c42\uff0c\u4e0e\u4e8b\u52a1\u5173\u7cfb\u5bc6\u5207\u7684\u662f\u8fde\u63a5\u3002\u8fd9\u662f\u56e0\u4e3a\u6570\u636e\u8282\u70b9\uff08DN\uff09\u4e5f\u5177\u5907\u5355\u4e2a DN \u5185\u7684\u4e8b\u52a1\u80fd\u529b\uff0cCN \u5219\u901a\u8fc7\u4e0e DN \u7684\u8fde\u63a5\u6765\u7ba1\u7406 DN \u4e0a\u7684\u4e8b\u52a1\uff0c\u4ece\u800c\u5b9e\u73b0\u5f3a\u4e00\u81f4\u7684\u5206\u5e03\u5f0f\u4e8b\u52a1\u80fd\u529b\u3002\u5176\u4e2d\u6d89\u53ca\u5230\u7684\u8fde\u63a5\u5927\u81f4\u5982\u4e0b\u56fe\u6240\u793a\uff1a<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042237273\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u5148\u7b80\u5355\u8bf4\u4e00\u4e0b\u8fd9\u91cc\u9762\u6d89\u53ca\u7684\u4e00\u4e9b\u8fde\u63a5\u3002ServerConnection\u00a0\u7c7b\u4f3c\u4e8e\u524d\u7aef\u8fde\u63a5\uff0c\u5927\u90e8\u5206\u7684 SQL \u8bed\u53e5\u6267\u884c\u7684\u5165\u53e3\u90fd\u662f\u00a0ServerConnection#innerExecute\u3002TConnection\u00a0\u4e2d\u7684\u00a0executeSQL\u00a0\u65b9\u6cd5\u8d1f\u8d23 SQL \u8bed\u53e5\u7684\u771f\u6b63\u6267\u884c\uff0c\u4e5f\u8d1f\u8d23\u521b\u5efa\u65b0\u7684\u4e8b\u52a1\u5bf9\u8c61\u3002TConnection\u00a0\u4f1a\u4e00\u76f4\u5f15\u7528\u7740\u8fd9\u4e2a\u4e8b\u52a1\u5bf9\u8c61\uff0c\u76f4\u5230\u4e8b\u52a1\u63d0\u4ea4\u6216\u56de\u6eda\u3002\u4e8b\u52a1\u5bf9\u8c61\u91cc\u6709\u4e00\u4e2a\u00a0TransactionConnectionHolder\uff0c\u8d1f\u8d23\u7ba1\u7406\u8be5\u4e8b\u52a1\u7528\u5230\u7684\u6240\u6709\u7269\u7406\u8fde\u63a5\uff08CN \u8fde\u63a5 DN \u7684\u79c1\u6709\u534f\u8bae\u8fde\u63a5\uff09\u3002\u503c\u5f97\u4e00\u63d0\u7684\u662f\uff0cExecutionContext\u00a0\u4f5c\u4e3a\u4e00\u6761\u903b\u8f91 SQL \u6267\u884c\u7684\u4e0a\u4e0b\u6587\uff0c\u4e5f\u4f1a\u5f15\u7528\u8fd9\u4e2a\u4e8b\u52a1\u5bf9\u8c61\u3002\u8fd9\u6837\uff0c\u540e\u7eed\u6267\u884c\u5668\u9700\u8981\u4f7f\u7528\u7269\u7406\u8fde\u63a5\u4e0e DN \u901a\u4fe1\u65f6\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7\u00a0ExecutionContext\u00a0\u62ff\u5230\u4e8b\u52a1\u5bf9\u8c61\uff0c\u518d\u901a\u8fc7\u4e8b\u52a1\u5bf9\u8c61\u7684\u00a0TransactionConnectionHolder\u00a0\u62ff\u5230\u5408\u9002\u7684\u7269\u7406\u8fde\u63a5\u3002\u4ee5\u4e0a\u7684\u5404\u79cd\u8fde\u63a5\uff0c\u90fd\u4f1a\u5728\u4e0b\u6587\u7ee7\u7eed\u8ba8\u8bba\u3002\u4e24\u4e2a\u4f8b\u5b50\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u4ee5\u4e24\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u6765\u8bf4\u660e\u4e8b\u52a1\u7684\u4e00\u751f\u5728 CN \u7684\u4ee3\u7801\u4e2d\u662f\u5982\u4f55\u4f53\u73b0\u7684\u3002\u6d4b\u8bd5\u7528\u8868\uff1aCREATE TABLE <code>tb1<\/code> (<\/p>\n<pre><code>`id` int PRIMARY KEY,\n`a` int<\/code><\/pre>\n<p>) DBPARTITION BY HASH(<code>id<\/code>)\u5148\u5728\u91cc\u9762\u63d2\u5165\u51e0\u6761\u6570\u636e\uff1aINSERT INTO tb1 VALUES (0, 0), (1, 1), (2, 2), (3, 3);\u6d4b\u8bd5\u4f7f\u7528\u7684\u4e24\u4e2a\u4f8b\u5b50\uff1a&#8211; Example 1: <br \/>BEGIN; <br \/>SELECT * FROM tb1 WHERE id = 0; <br \/>UPDATE tb1 SET a = 100 WHERE id = 1;<br \/>COMMIT;&#8211; Example 2: <br \/>BEGIN; <br \/>SELECT * FROM tb1 WHERE id = 0; <br \/>UPDATE tb1 SET a = 101 WHERE id = 1;<br \/>UPDATE tb1 SET a = 101 WHERE id = 0;<br \/>COMMIT;\u6ce8\u610f\u5230\u4f8b 2 \u53ea\u6bd4 \u4f8b 1 \u591a\u4fee\u6539\u4e86 id = 1 \u7684\u6570\u636e\u3002\u6d4b\u8bd5\u8868\u662f\u6309 id \u62c6\u5206\u7684\uff0c\u56e0\u6b64 id = 0 \u548c id = 1 \u7684\u8bb0\u5f55\u4f1a\u843d\u5728\u4e0d\u540c\u7684\u7269\u7406\u5206\u7247\u4e0a\uff08\u5047\u8bbe\u5206\u522b\u4e3a\u5206\u7247 0 \u548c\u5206\u7247 1\uff09\u3002\u4f8b 1 \u8bfb\u4e86\u5206\u7247 0\uff0c\u5199\u4e86\u5206\u7247 1\uff0c\u7136\u540e\u63d0\u4ea4\u4e86\u4e8b\u52a1\uff0c\u8fd9\u5c06\u4f1a\u89e6\u53d1\u6211\u4eec\u5bf9\u5355\u5206\u7247\u5199\u7684\u201c\u4e00\u9636\u6bb5\u63d0\u4ea4\u4f18\u5316\u201d\u3002\u4f8b 2 \u8bfb\u4e86\u5206\u7247 0\uff0c\u968f\u540e\u5199\u4e86\u5206\u7247 1 \u548c \u5206\u7247 0\uff0c\u7136\u540e\u63d0\u4ea4\u4e86\u4e8b\u52a1\uff0c\u8fd9\u5c06\u4f1a\u8fdb\u884c\u5b8c\u6574\u7684\u5206\u5e03\u5f0f\u4e8b\u52a1\u63d0\u4ea4\u6d41\u7a0b\u3002\u8fd9\u4e24\u4e2a\u4f8b\u5b50\u8fd8\u4f1a\u89e6\u53d1\u201c\u53ea\u8bfb\u8fde\u63a5\u4f18\u5316\u201d\uff0c\u5373\u53ea\u6709\u5728\u7b2c\u4e00\u6b21\u5199\u7684\u65f6\u5019\u624d\u771f\u6b63\u5f00\u542f\u5206\u5e03\u5f0f\u4e8b\u52a1\u3002\u5728\u63a5\u4e0b\u6765\u7684\u8ba8\u8bba\u4e2d\uff0c\u6211\u4eec\u9ed8\u8ba4\u4f7f\u7528 TSO \u4e8b\u52a1\u7b56\u7565\u548c RR \u7684\u9694\u79bb\u7ea7\u522b\u3002\u4f8b 1 \u4e8b\u52a1\u7684\u4e00\u751fBEGIN\u4e0e MySQL \u7c7b\u4f3c\uff0c\u8981\u5f00\u542f\u4e00\u4e2a\u4e8b\u52a1\uff0c\u4e00\u822c\u6709\u4e24\u79cd\u65b9\u5f0f\u3002\u7b2c\u4e00\u79cd\u65b9\u5f0f\u662f\u663e\u5f0f\u5730\u6267\u884c\u00a0BEGIN\u00a0\u6216\u00a0START TRANSACTION [transaction_characteristic]\uff0c\u6267\u884c\u8fd9\u4e24\u79cd\u8bed\u53e5\uff0c\u4f1a\u8c03\u7528\u00a0ServerConnection\u00a0\u4e2d\u7684\u00a0begin(boolean, IsolationLevel)\u00a0\u65b9\u6cd5\u3002\u7b2c\u4e8c\u79cd\u65b9\u5f0f\u662f\u6267\u884c\u00a0SET autocommit = 0\uff0c\u5f53\u524d session \u4f1a\u9690\u5f0f\u5f00\u542f\u4e8b\u52a1\uff0c\u8fd9\u79cd\u65b9\u5f0f\u4f1a\u8c03\u7528\u00a0ServerConnection\u00a0\u4e2d\u7684\u00a0setAutocommit(boolean, boolean)\u00a0\u65b9\u6cd5\u3002\u4e24\u79cd\u65b9\u5f0f\u90fd\u4f1a\u8c03\u7528\u00a0TConnection\u00a0\u7684\u00a0setAutoCommit\u00a0\u65b9\u6cd5\u3002\u8fd9\u4e9b\u65b9\u6cd5\u90fd\u53ea\u662f\u7b80\u5355\u5730\u8bb0\u5f55\u4e86\u4e00\u4e9b\u53d8\u91cf\uff08\u6bd4\u5982\u00a0transaction_characteristic\u00a0\u4e2d\u8bbe\u5b9a\u7684\u4e8b\u52a1\u76f8\u5173\u53d8\u91cf\uff09\uff0c\u540c\u65f6\u6807\u8bb0\u8fd9\u4e2a\u8fde\u63a5\u5f00\u542f\u4e86\u4e8b\u52a1\u3002\u6b64\u65f6\uff0c\u4e8b\u52a1\u5bf9\u8c61\u4e5f\u8fd8\u6ca1\u521b\u5efa\u51fa\u6765\uff0c\u4e5f\u6ca1\u6709\u4e0e\u540e\u7aef\u8fde\u63a5\u8fdb\u884c\u4efb\u4f55\u4ea4\u4e92\u3002\u8bfb\u5206\u7247 0\u5728\u5f00\u542f\u4e8b\u52a1\u540e\uff0c\u6267\u884c\u00a0SELECT * FROM tb1 WHERE id = 0\u00a0\u65f6\uff0c\u624d\u4f1a\u771f\u6b63\u521b\u5efa\u4e8b\u52a1\u5bf9\u8c61\u3002\u6839\u636e\u4e8b\u52a1\u4e0e\u8fde\u63a5\u4e2d\u7684\u8ba8\u8bba\uff0c\u5728\u00a0TConnection\u00a0\u4e2d\u8fd9\u6761\u903b\u8f91 SQL \u7684\u6267\u884c\u5165\u53e3\u4e3a\u00a0executeSQL\uff0c\u91cc\u9762\u4f1a\u771f\u6b63\u521b\u5efa\u4e8b\u52a1\u5bf9\u8c61\uff0c\u4e3b\u8981\u6267\u884c\u903b\u8f91\u4e3a\uff08\u4ee3\u7801\u51fa\u81ea PolarDB-X 5.4.12 release \u7248\u672c\uff0c\u4e3a\u4e86\u65b9\u4fbf\u8bf4\u660e\uff0c\u6709\u5220\u51cf\u53ca\u6539\u52a8\uff0c\u4e0b\u540c\uff09\uff1a\/\/ TConnection#executeSQL(ByteString, Parameters, TStatement, ExecutionContext)<br \/>public ResultSet executeSQL(ByteString sql, Parameters params, TStatement stmt,<\/p>\n<pre><code>                            ExecutionContext executionContext) throws SQLException {<\/code><\/pre>\n<p>if (this.trx == null || this.trx.isClosed()) {<\/p>\n<pre><code>\/\/ \u5f00\u542f\u4e8b\u52a1\u540e\uff0c\u76f4\u5230\u6267\u884c\u7b2c\u4e00\u6761\u8bed\u53e5\uff0c\u624d\u4f1a\u521b\u5efa\u4e8b\u52a1\u5bf9\u8c61\u3002\nbeginTransaction();<\/code><\/pre>\n<p>}<br \/>  \/\/ \u8ba9 executionContext \u5f15\u7528 trx \u5bf9\u8c61\uff0c\u65b9\u4fbf\u540e\u7eed\u6267\u884c\u5668\u901a\u8fc7 trx \u5bf9\u8c61\u62ff\u7269\u7406\u8fde\u63a5\u3002<br \/>  executionContext.setTransaction(this.trx);<br \/>  resultCursor = executeQuery(sql, executionContext, trxPolicyModified);<br \/>}<br \/>\/\/ TConnection#beginTransaction(boolean)<br \/>private void beginTransaction(boolean autoCommit) {<br \/>  \/\/ \u6839\u636e\u4e00\u4e9b\u9ed8\u8ba4\u7684\u6216\u7528\u6237\u8bbe\u5b9a\u7684\u4e8b\u52a1\u53d8\u91cf\uff0c\u9009\u62e9\u5408\u9002\u7684\u4e8b\u52a1\u7b56\u7565\uff0c\u6bd4\u5982 TSO\/XA \u7b49\u3002<br \/>  trxPolicy = loadTrxPolicy(executionContext);<br \/>  TransactionClass trxConfig = trxPolicy.getTransactionType(autoCommit, readOnly);<br \/>  \/\/ \u6839\u636e\u4e8b\u52a1\u7b56\u7565\uff0c\u521b\u5efa\u51fa\u5bf9\u5e94\u7684\u4e8b\u52a1\u5bf9\u8c61\u3002<br \/>  this.trx = transactionManager.createTransaction(trxConfig, executionContext);<br \/>}\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u5982\u679c\u5728\u4e0a\u8ff0\u4ee3\u7801\u6253\u4e2a\u65ad\u70b9\uff0c\u53ef\u4ee5\u770b\u5230\u521b\u5efa\u51fa\u6765\u7684\u662f TsoTransaction\uff0c\u5176\u4e2d\u4e00\u4e9b\u503c\u5f97\u5173\u6ce8\u7684\u53d8\u91cf\u4e3a\uff1atrx = {TsoTransaction}<\/p>\n<pre><code>\/\/ \u6b64\u65f6\u8fd8\u6ca1\u6709\u83b7\u53d6\u4efb\u4f55\u65f6\u95f4\u6233\u3002\nsnapshotTimestamp = -1\ncommitTimestamp = -1\n\/\/ \u4e8b\u52a1\u5199\u7684\u7b2c\u4e00\u4e2a\u7269\u7406\u5206\u7247\uff08\u4e0b\u79f0\u4e3b\u5206\u7247\uff09\uff0c\u4e8b\u52a1\u65e5\u5fd7\u5c06\u4f1a\u5199\u5728\u8fd9\u4e2a\u5206\u7247\u4e0a\u3002\nprimaryGroup = null\n\/\/ \u8be5\u4e8b\u52a1\u662f\u5426\u8de8\u5206\u7247\uff0c\u5982\u679c\u662f\u5355\u5206\u7247\u4e8b\u52a1\uff0c\u4f1a\u4f18\u5316\u4e3a\u4e00\u9636\u6bb5\u63d0\u4ea4\u3002\nisCrossGroup = false\n\/\/ \u4e8b\u52a1\u65e5\u5fd7\u7ba1\u7406\u5668\uff0c\u8d1f\u8d23\u5199\u4e8b\u52a1\u65e5\u5fd7\u3002\nglobalTxLogManager = {GlobalTxLogManager}\n\/\/ \u5206\u5e03\u5f0f\u4e8b\u52a1\u7684 connectionHolder \u90fd\u662f TransactionConnectionHolder\uff0c\n\/\/ \u91cc\u9762\u5206\u522b\u5b58\u50a8\u4e86\u8bfb\u5199\u8fde\u63a5\uff0c\u8bfb\u8fde\u63a5\u548c\u5199\u8fde\u63a5\u5728\u63d0\u4ea4\u65f6\u884c\u4e3a\u4f1a\u6709\u6240\u4e0d\u540c\u3002\nconnectionHolder = {TransactionConnectionHolder}\n    \/\/ \u7269\u7406\u5206\u7247\u5230\u5bf9\u5e94\u5199\u8fde\u63a5\u7684\u6620\u5c04\u3002\n    groupHeldWriteConn = {HashMap}\n    \/\/ \u7269\u7406\u5206\u7247\u5230\u5bf9\u5e94\u8bfb\u8fde\u63a5\u96c6\u5408\u5230\u6620\u5c04\u3002\u5728 ShareReadView \u4f18\u5316\u5f00\u542f\u65f6\uff0c\n    \/\/ \u53ef\u4ee5\u540c\u65f6\u5b58\u5728\u591a\u4e2a\u8bfb\u8fde\u63a5\u548c\u4e00\u4e2a\u5199\u8fde\u63a5\uff0c\u56e0\u6b64\u8fd9\u91cc\u8bfb\u5199\u8fde\u63a5\u9700\u8981\u5206\u5f00\u7ba1\u7406\u3002\n    \/\/ \u8be5\u4f18\u5316\u4e0d\u5728\u672c\u6587\u5c55\u5f00\u3002\n    groupHeldReadConns = {HashMap}\u5728\u6267\u884c\u5668\u9636\u6bb5\uff0c\u4f1a\u9009\u62e9\u7ed9\u5206\u7247 0 \u4e0b\u53d1\u4e00\u6761 SELECT \u8bed\u53e5\uff0c\u6b64\u65f6\u9700\u8981\u83b7\u53d6\u5206\u7247 0 \u7684\u7269\u7406\u8fde\u63a5\uff0c\u4ee3\u7801\u5165\u53e3\u662f\u00a0MyJdbcHandler\u00a0\u4e2d\u7684\u00a0getPhyConnection(ITransaction, ITransaction.RW, String, DataSource)\u00a0\u65b9\u6cd5\u3002\u5176\u4e2d\u7684\u4e8b\u52a1\u5bf9\u8c61\u00a0Transaction\u00a0\u5219\u662f\u4ece\u00a0ExecutionContext\u00a0\u91cc\u62ff\u5230\u3002\u8be5\u65b9\u6cd5\u6700\u540e\u4f1a\u8c03\u7528\u00a0AbstractTransaction\u00a0\uff08\u8fd9\u662f\u6240\u6709\u5206\u5e03\u5f0f\u4e8b\u52a1\u7c7b\u7684\u57fa\u7c7b\uff09\u4e2d\u7684\u00a0getConnection\u00a0\u65b9\u6cd5\u3002\u901a\u8fc7\u4e8b\u52a1\u62ff\u7269\u7406\u8fde\u63a5\u7684\u4ee3\u7801\u00a0AbstractTransaction#getConnection\u00a0\u5982\u4e0b\uff1a\/\/ AbstractTransaction#getConnection(String, String, IDataSource, RW, ExecutionContext)<\/code><\/pre>\n<p>public IConnection getConnection(String schema, String group, IDataSource ds, RW rw, ExecutionContext ec) {<br \/>  if (\/<em> \u662f\u4e8b\u52a1\u7684\u7b2c\u4e00\u4e2a\u5199\u8bf7\u6c42 <\/em>\/) {<\/p>\n<pre><code>\/\/ \u628a\u8fd9\u4e2a\u5206\u7247\u4f5c\u4e3a\u4e3b\u5206\u7247\uff0c\u4e8b\u52a1\u65e5\u5fd7\u5c06\u5199\u5728\u8fd9\u4e2a\u5206\u7247\u4e0a\u3002\nthis.primaryGroup = group;\n\/\/ \u8be5\u5206\u7247\u8fd8\u7528\u4e8e\u751f\u6210 XA \u4e8b\u52a1\u7684 xid\u3002\nthis.primaryGroupUid = IServerConfigManager.getGroupUniqueId(schema, group);<\/code><\/pre>\n<p>}<br \/>  \/\/ \u901a\u8fc7 connectionHolder \u62ff\u5230\u7269\u7406\u8fde\u63a5\u3002<br \/>  IConnection conn = connectionHolder.getConnection(schema, group, ds, rw);<br \/>  if (\/<em> \u662f\u5199\u8bf7\u6c42 <\/em>\/ &#038;&#038; !isCrossGroup &#038;&#038; !this.primaryGroup.equals(group)) {<\/p>\n<pre><code>\/\/ \u4e8b\u52a1\u6d89\u53ca\u4e86\u591a\u4e2a\u5206\u7247\u3002\nthis.isCrossGroup = true;<\/code><\/pre>\n<p>}<br \/>  return conn;<br \/>}\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e0a\u8ff0\u53c2\u6570 group \u662f\u7269\u7406\u5206\u7247 0\uff0crw \u662f READ\uff0c\u8bf4\u660e\u9700\u8981\u7269\u7406\u5206\u7247 0 \u4e0a\u7684\u8bfb\u8fde\u63a5\uff0cds \u5219\u4e3b\u8981\u7528\u4e8e\u751f\u6210\u7269\u7406\u8fde\u63a5\u3002\u7531\u4e8e\u6211\u4eec\u53ea\u662f\u8bfb\u8bf7\u6c42\uff0c\u56e0\u6b64\u5206\u7247 0 \u4e0d\u4f1a\u4f5c\u4e3a\u4e3b\u5206\u7247\uff0c\u4f1a\u76f4\u63a5\u8fd4\u56de\u00a0connectionHolder.getConnection(schema, group, ds, rw)\u00a0\u7684\u7ed3\u679c\u3002\u901a\u8fc7\u8fde\u63a5\u7ba1\u7406\u5668\u62ff\u7269\u7406\u8fde\u63a5\u7684\u4ee3\u7801\u00a0TransactionConnectionHolder#getConnection\u00a0\u5982\u4e0b\uff1a\/\/ TransactionConnectionHolder#getConnection(String, String, IDataSource, RW)<br \/>public IConnection getConnection(String schema, String group, IDataSource ds, RW rw) {<br \/>  \/\/ \u5c1d\u8bd5\u83b7\u53d6\u8be5\u5206\u7247\u4e0a\u7684\u5199\u8fde\u63a5\uff0c\u5982\u679c\u6709\uff0c\u76f4\u63a5\u8fd4\u56de\u8fd9\u4e2a\u5199\u8fde\u63a5\u3002<br \/>  HeldConnection groupWriteConn = groupHeldWriteConn.get(group);<br \/>  if (groupWriteConn != null) {<\/p>\n<pre><code>return groupWriteConn.connection;<\/code><\/pre>\n<p>}<\/p>\n<p>HeldConnection freeReadConn = \/<em> \u5c1d\u8bd5\u627e\u5230\u8bfb\u8fde\u63a5 <\/em>\/;<br \/>  if (freeReadConn != null) {<\/p>\n<pre><code>if (\/* \u5f53\u524d\u9700\u8981\u5199\u8fde\u63a5 *\/) {\n  \/\/ \u8bbe\u7f6e\u5f53\u524d\u8fde\u63a5\u4e3a\u5199\u8fde\u63a5\uff0cparticipated = true \u610f\u5473\u7740\u8be5\u8fde\u63a5\u662f\u5199\u8fde\u63a5\u3002\n  freeReadConn.participated = true;\n  this.groupHeldWriteConn.put(group, freeReadConn);\n  \/\/ \u7531\u4e8e\u539f\u672c\u662f\u8bfb\u8fde\u63a5\uff0c\u8fd9\u91cc\u624d\u771f\u6b63\u5f00\u542f\u5206\u5e03\u5f0f\u4e8b\u52a1\u3002\n  this.trx.commitNonParticipant(group, freeReadConn.connection);\n  this.trx.begin(schema, freeReadConn.group, freeReadConn.connection);\n}\nreturn freeReadConn.connection;<\/code><\/pre>\n<p>}<br \/>  \/\/ \u5f53\u524d\u5206\u7247\u6ca1\u6709\u4efb\u4f55\u8fde\u63a5\uff0c\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u8fde\u63a5\u3002\u8fd8\u4f1a\u6839\u636e\u8bfb\u5199\u7c7b\u578b\uff0c<br \/>  \/\/ \u8bbe\u7f6e\u597d\u5199\u8fde\u63a5 groupHeldWriteConn \u6216\u8bfb\u8fde\u63a5\u96c6\u5408 groupHeldReadConns\u3002<br \/>  IConnection conn = new DeferredConnection(\/<em> \u8fd9\u91cc\u4f1a\u83b7\u53d6\u5e76\u5c01\u88c5\u8be5\u5206\u7247\u7684\u79c1\u6709\u534f\u8bae\u8fde\u63a5 <\/em>\/);<br \/>  if (\/<em> \u9700\u8981\u5199\u8fde\u63a5 <\/em>\/) {<\/p>\n<pre><code>\/\/ \u5f00\u542f\u6b63\u5e38\u7684\u5206\u5e03\u5f0f\u4e8b\u52a1\u3002\nthis.trx.begin(schema, group, conn);<\/code><\/pre>\n<p>} else {<\/p>\n<pre><code>\/\/ \u4f18\u5316\u4e3a\u53ea\u8bfb\u4e8b\u52a1\u3002\nthis.trx.beginNonParticipant(group, conn);<\/code><\/pre>\n<p>}<br \/>  return conn;<br \/>}\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u7531\u4e8e\u662f\u7b2c\u4e00\u6761\u8bed\u53e5\uff0c\u8be5\u5206\u7247\u4e0a\u8fd8\u6ca1\u6709\u4efb\u4f55\u8fde\u63a5\uff0c\u56e0\u6b64\u4f1a\u5148\u751f\u6210\u4e00\u4e2a\u8fde\u63a5\u8be5\u5206\u7247\u7684\u79c1\u6709\u534f\u8bae\u8fde\u63a5\uff0c\u5305\u88c5\u6210\u00a0DeferredConnection\uff0c\u7136\u540e\u56e0\u4e3a\u662f\u8bfb\u8bf7\u6c42\uff0c\u4f1a\u8c03\u7528\u00a0beginNonParticipant\u00a0\u3002TsoTransaction\u00a0\u7684\u00a0beginNonParticipant\u00a0\u65b9\u6cd5\u5982\u4e0b\uff1a\/\/ TsoTransaction#beginNonParticipant(String, IConnection)<br \/>protected void beginNonParticipant(String group, IConnection conn) throws SQLException {<br \/>  if (snapshotTimestamp &lt; 0) {<\/p>\n<pre><code>\/\/ \u8be5\u4e8b\u52a1\u4ece\u672a\u62ff\u8fc7\u65f6\u95f4\u6233\uff0c\u5219\u5728\u8fd9\u91cc\u83b7\u53d6\u3002\nsnapshotTimestamp = nextTimestamp();<\/code><\/pre>\n<p>}<br \/>  \/\/ \u4f7f\u7528\u79c1\u6709\u534f\u8bae\u7684\u6d41\u6c34\u7ebf\u6267\u884c\u673a\u5236\u6267\u884c BEGIN\u3002<br \/>  conn.executeLater(&#8220;BEGIN&#8221;);<br \/>  \/\/ \u5728 BEGIN \u540e\u53d1\u9001\u65f6\u95f4\u6233\u3002<br \/>  sendSnapshotSeq(conn);<br \/>}\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u79c1\u6709\u534f\u8bae\u8fde\u63a5\u4f1a\u6d41\u6c34\u7ebf\u6267\u884c\u00a0BEGIN\u00a0\u8bed\u53e5\uff08\u975e\u963b\u585e\uff0c\u4e0d\u7b49\u7ed3\u679c\u8fd4\u56de\uff09\uff0c\u4e14\u5728\u7a0d\u540e\u6267\u884c\u7269\u7406 SQL \u65f6\u624d\u53d1\u9001\u65f6\u95f4\u6233\u3002\u81f3\u6b64\uff0c\u8fde\u63a5\u4e0a\u7684\u4e00\u4e9b\u521d\u59cb\u5316\u64cd\u4f5c\u5df2\u7ecf\u5b8c\u6210\uff0c\u53ef\u4ee5\u5411\u6267\u884c\u5668\u8fd4\u56de\u5e76\u6267\u884c\u8bfb\u5206\u7247 0 \u7684\u7269\u7406 SQL\u3002\u5199\u5206\u7247 1\u968f\u540e\uff0c\u6211\u4eec\u6267\u884c\u00a0UPDATE tb1 SET a = 100 WHERE id = 1\u3002\u5728\u6267\u884c\u5668\u9636\u6bb5\uff0c\u9700\u8981\u7ed9\u5206\u7247 1 \u4e0b\u53d1\u4e00\u6761 UPDATE \u8bed\u53e5\uff0c\u6b64\u65f6\u9700\u8981\u83b7\u53d6\u5206\u7247 1 \u7684\u7269\u7406\u8fde\u63a5\uff0c\u56e0\u6b64\u53c8\u4f1a\u8c03\u7528\u00a0AbstractTransaction#getConnection\u00a0\u65b9\u6cd5\uff0c\u901a\u8fc7\u4e8b\u52a1\u5bf9\u8c61\u62ff\u7269\u7406\u8fde\u63a5\u3002\u901a\u8fc7\u524d\u9762\u8d34\u51fa\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u53d1\u73b0\u7531\u4e8e\u662f\u4e8b\u52a1\u7684\u7b2c\u4e00\u4e2a\u5199\u8bf7\u6c42\uff0c\u56e0\u6b64\u5206\u7247 1 \u4f1a\u89c6\u4f5c\u4e3b\u5206\u7247\uff0c\u7528\u4e8e\u751f\u6210 xid \u548c\u7a0d\u540e\u8bb0\u5f55\u4e8b\u52a1\u65e5\u5fd7\u3002\u5728\u83b7\u53d6\u7269\u7406\u8fde\u63a5\u65f6\uff0c\u53c8\u4f1a\u8c03\u7528\u00a0TransactionConnectionHolder#getConnection\u00a0\u65b9\u6cd5\uff0c\u901a\u8fc7\u8fde\u63a5\u7ba1\u7406\u5668\u62ff\u7269\u7406\u8fde\u63a5\u3002\u901a\u8fc7\u524d\u9762\u8d34\u51fa\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u53d1\u73b0\u7531\u4e8e\u5206\u7247 1 \u6ca1\u6709\u4efb\u4f55\u8fde\u63a5\uff0c\u56e0\u6b64\u4f1a\u751f\u6210\u4e00\u4e2a\u79c1\u6709\u534f\u8bae\u8fde\u63a5\uff0c\u5305\u88c5\u6210\u00a0DeferredConnection\u3002\u4e0e\u8bfb\u5206\u7247 0 \u4e0d\u540c\uff0c\u7531\u4e8e\u662f\u5199\u8bf7\u6c42\uff0c\u4f1a\u6267\u884c\u00a0TsoTransaction\u00a0\u7684\u00a0begin\u00a0\u65b9\u6cd5\u3002TsoTransaction\u00a0\u7684\u00a0begin\u00a0\u65b9\u6cd5\u5982\u4e0b\uff1a\/\/ TsoTransaction#begin(String, String, IConnection)<br \/>protected void begin(String schema, String group, IConnection conn) throws SQLException {<br \/>  if (snapshotTimestamp &lt; 0) {<\/p>\n<pre><code>\/\/ \u8be5\u4e8b\u52a1\u4ece\u672a\u62ff\u8fc7\u65f6\u95f4\u6233\uff0c\u5219\u5728\u8fd9\u91cc\u83b7\u53d6\u3002\nsnapshotTimestamp = nextTimestamp();<\/code><\/pre>\n<p>}<br \/>  \/\/ \u83b7\u53d6 xid\u3002<br \/>  String xid = getXid(group);<br \/>  \/\/ \u89e6\u53d1\u79c1\u6709\u534f\u8bae\u6d41\u6c34\u7ebf\u6267\u884c XA START\u3002<br \/>  conn.executeLater(&#8220;XA START &#8221; + xid);<br \/>  \/\/ \u5728 XA START \u540e\u53d1\u9001\u65f6\u95f4\u6233\u3002<br \/>  sendSnapshotSeq(conn);<br \/>}\u7b80\u5355\u6765\u8bf4\uff0c\u548c\u6b64\u524d\u00a0beginNonParticipant\u00a0\u65b9\u6cd5\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff0c\u4f7f\u7528\u4e86\u00a0XA START\u00a0\u5f00\u542f\u4e8b\u52a1\u3002\u6839\u636e\u00a0MySQL \u5173\u4e8e XA \u4e8b\u52a1\u7684\u8bf4\u660e\uff0cxid \u7531\u00a0gtrid [, bqual [, formatID ]]\u00a0\u7ec4\u6210\uff0c\u8fd9\u91cc\u7684\u00a0gtrid\u00a0\u662f\u201cdrds-\u4e8b\u52a1 id @\u4e3b\u5206\u7247Uid\u201d\uff0c\u8fd9\u6837\u4fdd\u8bc1\u4e86\u540c\u4e00\u4e2a\u4e8b\u52a1\u5728\u4e0d\u540c\u5206\u7247\u4e0a\u6267\u884c\u00a0XA START\uff0c\u4f1a\u4f7f\u7528\u76f8\u540c\u7684\u00a0gtrid\u3002bqual\u00a0\u8bbe\u7f6e\u5f53\u524d\u8fde\u63a5\u7684\u5206\u7247\uff0c\u7528\u4e8e\u5728\u4e8b\u52a1\u6062\u590d\u65f6\u786e\u5b9a\u5206\u652f\u4e8b\u52a1\u6240\u5728\u7684\u5206\u7247\u3002 \u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0cxid \u4e3a\uff1a&#8217;drds-13e101d74e400000@5ae6c3b5be613cd1&#8242;, &#8216;DB1_000001_GROUP&#8217;\uff0c\u5176\u4e2d\u00a013e101d74e400000\u00a0\u662f\u4e8b\u52a1 id\uff0c5ae6c3b5be613cd1\u00a0\u662f\u5206\u7247 1 \u7684 Uid\uff0cDB1_000001_GROUP\u00a0\u662f\u5206\u7247 1 \u7684\u5177\u4f53\u5206\u7247\u540d\u79f0\u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8fd9\u91cc\u4f1a\u628a\u4e4b\u524d\u7684\u65f6\u95f4\u6233\u53d1\u9001\u5230\u5206\u7247 1\u3002\u81f3\u6b64\uff0c\u8fde\u63a5\u4e0a\u7684\u4e00\u4e9b\u521d\u59cb\u5316\u64cd\u4f5c\u5df2\u7ecf\u5b8c\u6210\uff0c\u53ef\u4ee5\u5411\u6267\u884c\u5668\u8fd4\u56de\u5e76\u6267\u884c\u5199\u5206\u7247 1 \u7684\u7269\u7406 SQL\u3002COMMIT\u6700\u540e\uff0c\u6267\u884c\u00a0COMMIT\u00a0\u63d0\u4ea4\u4e8b\u52a1\u3002\u5904\u7406\u00a0COMMIT\u00a0\u7684\u4ee3\u7801\u5165\u53e3\u4e3a\u00a0ServerConnection#commit()\uff0c\u5176\u4e3b\u8981\u8c03\u7528\u4e86\u00a0TConnection#commit\u00a0\u65b9\u6cd5\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ TConnection#commit()<br \/>public void commit() throws SQLException {<br \/>  try {<\/p>\n<pre><code>\/\/ \u89e6\u53d1\u4e8b\u52a1\u7684\u63d0\u4ea4\u6d41\u7a0b\u3002\nthis.trx.commit();<\/code><\/pre>\n<p>} finally {<\/p>\n<pre><code>\/\/ \u5927\u90e8\u5206\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u4e8b\u52a1\u63d0\u4ea4\u6210\u529f\uff0c\u6216\u51fa\u73b0\u5f02\u5e38\u540e\u6b63\u786e\u5904\u7406\u4e86\uff0c\n\/\/ \u6240\u6709\u8fde\u63a5\u4f1a\u88ab\u5173\u95ed\u5e76\u91ca\u653e\uff0ctrx.close() \u76f8\u5f53\u4e8e\u4ec0\u4e48\u4e5f\u4e0d\u505a\u3002\n\/\/ \u4f46\u5982\u679c\u4e8b\u52a1\u63d0\u4ea4\u5931\u8d25\u4e14\u6ca1\u6709\u5904\u7406\uff0c\u8fd9\u91cc\u4f1a\u56de\u6eda\u4e8b\u52a1\u5e76\u91ca\u653e\u6240\u6709\u7269\u7406\u8fde\u63a5\u3002\nthis.trx.close();\n\/\/ \u53bb\u6389\u5bf9\u8fd9\u4e2a\u4e8b\u52a1\u5bf9\u8c61\u7684\u5f15\u7528\uff0c\u610f\u5473\u7740\u5f53\u524d\u8fde\u63a5\u91cc\u8fd9\u4e2a\u4e8b\u52a1\u4e00\u751f\u7684\u7ed3\u675f\u3002\nthis.trx = null;<\/code><\/pre>\n<p>}<br \/>}\u6211\u4eec\u91cd\u70b9\u5173\u6ce8\u4e00\u4e0b\u4e8b\u52a1\u7684\u63d0\u4ea4\u6d41\u7a0b\uff0c\u4e0a\u8ff0\u00a0this.trx.commit()\u00a0\u8c03\u7528\u65f6\uff0c\u4f1a\u8c03\u7528\u00a0ShareReadViewTransaction\uff08\u8be5\u7c7b\u7ee7\u627f\u4e86\u00a0AbstractTransaction\uff0c\u57fa\u4e8e XA \u4e8b\u52a1\u5b9e\u73b0\u4e86\u5171\u4eab readview \u7684\u529f\u80fd\uff0cXATransaction \u548c TsoTransaction \u90fd\u4f1a\u7ee7\u627f\u8fd9\u4e2a\u7c7b\uff0c\u5728\u8fd9\u91cc\u53ef\u4ee5\u7b80\u5355\u7406\u89e3\u4e3a XA \u4e8b\u52a1\u7684\u57fa\u7c7b\uff09\u7684\u00a0commit\u00a0\u65b9\u6cd5\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ ShareReadViewTransaction#commit()<br \/>public void commit() {<br \/>  if (!isCrossGroup) {<\/p>\n<pre><code>\/\/ \u5982\u679c\u53ea\u6d89\u53ca\u4e86\u5355\u4e2a\u5206\u7247\u7684\u5199\uff0c\u8fdb\u884c\u4e00\u9636\u6bb5\u63d0\u4ea4\u4f18\u5316\u3002\ncommitOneShardTrx();<\/code><\/pre>\n<p>} else {<\/p>\n<pre><code>\/\/ \u6b63\u5e38\u7684\u591a\u5206\u7247\u5206\u5e03\u5f0f\u4e8b\u52a1\u63d0\u4ea4\u6d41\u7a0b\u3002\ncommitMultiShardTrx();<\/code><\/pre>\n<p>}<br \/>}\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u7531\u4e8e\u53ea\u5199\u4e86\u5206\u7247 1\uff0c\u6240\u4ee5\u8fdb\u5165\u4e00\u9636\u6bb5\u63d0\u4ea4\u4f18\u5316\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ ShareReadViewTransaction#commitOneShardTrx()<br \/>protected void commitOneShardTrx() {<br \/>  \/\/ \u5bf9\u6301\u6709\u7684\u6240\u6709\u7269\u7406\u8fde\u63a5\u6267\u884c\u4ee5\u4e0b\u6d41\u7a0b\uff0c\u4ee5\u63d0\u4ea4\u6bcf\u4e2a\u7269\u7406\u8fde\u63a5\u5f00\u542f\u7684\u4e8b\u52a1\u3002<br \/>  forEachHeldConnection((group, conn, participated) -&gt; {<\/p>\n<pre><code>  if (!participated) {\n    \/\/ \u53ea\u8bfb\u8fde\u63a5\u662f BEGIN \u5f00\u542f\u4e8b\u52a1\u7684\uff0c\u4e14\u53ea\u6709\u8bfb\u64cd\u4f5c\uff0c\u6267\u884c ROLLBACK \u5373\u53ef\u3002\n    conn.execute(&quot;ROLLBACK&quot;);\n  } else {\n    \/\/ \u83b7\u53d6 xid\u3002\n      String xid = getXid(group);\n    \/\/ \u5199\u8fde\u63a5\u662f XA START \u5f00\u542f\u4e8b\u52a1\u7684\uff0c\u6267\u884c XA END \u548c XA COMMIT ONE PHASE \u63d0\u4ea4\u4e8b\u52a1\u3002\n    conn.execute(&quot;XA END &quot; + xid + &quot;; XA COMMIT &quot; + xid + &quot; ONE PHASE&quot;);\n  }<\/code><\/pre>\n<p>});<br \/>  \/\/ \u6240\u6709\u8fde\u63a5\u90fd\u63d0\u4ea4\u4e86\u5206\u652f\u4e8b\u52a1\uff0c\u91ca\u653e\u5e76\u6e05\u7a7a\u8fd9\u4e9b\u7269\u7406\u8fde\u63a5\u3002<br \/>  connectionHolder.closeAllConnections();<br \/>}\u6211\u4eec\u4e00\u5171\u6301\u6709\u4e86 2 \u4e2a\u7269\u7406\u8fde\u63a5\u3002\u5bf9\u4e8e\u5206\u7247 0 \u7684\u53ea\u8bfb\u8fde\u63a5\uff0c\u4f1a\u76f4\u63a5\u6267\u884c\u00a0ROLLBACK\uff1b\u5bf9\u4e8e\u5206\u7247 1 \u7684\u5199\u8fde\u63a5\uff0c\u5219\u6267\u884c\u00a0XA END\u00a0\u548c\u00a0XA COMMIT ONE PHASE\u00a0\u63d0\u4ea4\u4e8b\u52a1\u3002\u6ce8\u610f\u5230\u6211\u4eec\u5e76\u6ca1\u6709\u83b7\u53d6 commit timestamp\uff0c\u56e0\u4e3a\u5728\u4e00\u9636\u6bb5\u63d0\u4ea4\u4f18\u5316\u91cc\uff0ccommit timestamp \u4f1a\u7531 InnoDB \u8ba1\u7b97\u751f\u6210\uff1a\u5177\u4f53\u7684\u8ba1\u7b97\u89c4\u5219\u662f\uff1aCOMMIT_TS = MAX_SEQUENCE + 1\uff0c\u5176\u4e2d MAX_SEQUENCE \u4e3a InnoDB \u672c\u5730\u7ef4\u62a4\u7684\u5386\u53f2\u6700\u5927\u7684 snapshot_ts\u3002\u5982\u679c\u63d0\u4ea4\u5931\u8d25\u4e86\uff0c\u4f1a\u8c03\u7528\u4e8b\u52a1\u7684\u00a0close\u00a0\u65b9\u6cd5\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ AbstractTransaction#close()<br \/>public void close() {<br \/>  \/\/ \u56de\u6eda\u6240\u6709\u7269\u7406\u8fde\u63a5\u4e0a\u7684\u4e8b\u52a1\u3002<br \/>  cleanupAllConnections();<br \/>  \/\/ \u91ca\u653e\u5e76\u6e05\u7a7a\u8fd9\u4e9b\u7269\u7406\u8fde\u63a5\u3002<br \/>  connectionHolder.closeAllConnections();<br \/>}\u503c\u5f97\u4e00\u63d0\u7684\u662f\uff0ccleanupAllConnections()\u00a0\u4e5f\u662f\u00a0ROLLBACK\u00a0\u8bed\u53e5\u4e3b\u8981\u8c03\u7528\u7684\u65b9\u6cd5\u3002\u56e0\u6b64\u4e3a\u4e86\u540c\u65f6\u4e86\u89e3\u00a0ROLLBACK\u00a0\u8bed\u53e5\u6267\u884c\u6d41\u7a0b\uff0c\u6211\u4eec\u4e5f\u770b\u4e00\u4e0b\u00a0cleanupAllConnections\u00a0\u65b9\u6cd5\u7684\u4ee3\u7801\uff1a\/\/ AbstractTransaction#cleanupAllConnections()<br \/>protected final void cleanupAllConnections() {<br \/>  \/\/ \u5bf9\u6301\u6709\u7684\u6240\u6709\u7269\u7406\u8fde\u63a5\u6267\u884c\u4ee5\u4e0b\u6d41\u7a0b\uff0c\u4ee5\u56de\u6eda\u6bcf\u4e2a\u7269\u7406\u8fde\u63a5\u5f00\u542f\u7684\u4e8b\u52a1\u3002<br \/>  forEachHeldConnection((group, conn, participated) -&gt; {<\/p>\n<pre><code>if (conn.isClosed()) { return; }\nif (!participated) {\n  \/\/ \u53ea\u8bfb\u8fde\u63a5\u662f BEGIN \u5f00\u542f\u4e8b\u52a1\u7684\uff0c\u4e14\u53ea\u6709\u8bfb\u64cd\u4f5c\uff0c\u6267\u884c ROLLBACK \u5373\u53ef\u3002\n  conn.execute(&quot;ROLLBACK&quot;);\n} else {\n  \/\/ \u83b7\u53d6 xid\u3002\n    String xid = getXid(group);\n  \/\/ \u5199\u8fde\u63a5\u662f XA START \u5f00\u542f\u4e8b\u52a1\u7684\uff0c\u6267\u884c XA END \u548c XA ROLLBACK \u56de\u6eda\u4e8b\u52a1\u3002\n  conn.execute(&quot;XA END &quot; + xid + &quot;; XA ROLLBACK &quot; + xid);\n}<\/code><\/pre>\n<p>});<br \/>}\u53ef\u4ee5\u770b\u5230\uff0c\u56de\u6eda\u7684\u903b\u8f91\u662f\u770b\u60c5\u51b5\u6267\u884c\u00a0ROLLBACK\u00a0\u6216\u00a0XA ROLLBACK\u00a0\u6765\u56de\u6eda\u4e8b\u52a1\u7684\u3002\u81f3\u6b64\uff0c\u6211\u4eec\u770b\u5230\u4e86\u4f8b 1 \u4e8b\u52a1\u7684\u4e00\u751f\u3002\u63a5\u4e0b\u6765\u770b\u4e00\u4e0b\u591a\u5206\u7247\u5199\u7684\u4e8b\u52a1\u6d41\u7a0b\u3002\u4f8b 2 \u4e8b\u52a1\u7684\u4e00\u751f\u5199\u5206\u7247 0\u4f8b 2 \u4e2d\uff0c\u4ece\u5f00\u542f\u4e8b\u52a1\u5230\u6267\u884c\u00a0UPDATE tb1 SET a = 100 WHERE id = 1\u00a0\u8d70\u7684\u6d41\u7a0b\u548c\u4f8b 1 \u4e00\u6837\uff0c\u76f4\u5230\u6267\u884c\u00a0UPDATE tb1 SET a = 100 WHERE id = 0\u00a0\u65f6\uff0c\u624d\u6709\u6240\u4e0d\u540c\u3002\u5177\u4f53\u800c\u8a00\uff0c\u4e8b\u52a1\u5728\u4e4b\u524d\u5c31\u83b7\u53d6\u4e86\u5206\u7247 0 \u7684\u53ea\u8bfb\u8fde\u63a5\uff0c\u5f53\u6267\u884c\u5230\u00a0TransactionConnectionHolder#getConnection\u00a0\u65f6\uff0c\u4f1a\u5148\u63d0\u4ea4\u53ea\u8bfb\u8fde\u63a5\u4e0a\u7684\u4e8b\u52a1\uff08\u5b9e\u9645\u6267\u884c\u4e86\u00a0ROLLBACK\uff09\uff0c\u7136\u540e\u5728\u8fd9\u6761\u8fde\u63a5\u4e0a\u7528\u00a0XA START\u00a0\u5f00\u542f XA \u4e8b\u52a1\uff0c\u8bbe\u7f6e\u597d\u65f6\u95f4\u6233\uff0c\u5c31\u53ef\u4ee5\u628a\u8fd9\u4e2a\u7269\u7406\u8fde\u63a5\u8fd4\u56de\u7ed9\u6267\u884c\u5668\uff0c\u6700\u7ec8\u6267\u884c\u7269\u7406 SQL\u3002\u7531\u4e8e\u8fd9\u662f\u7b2c\u4e8c\u4e2a\u5199\u8fde\u63a5\uff0c\u56e0\u6b64\u8fd8\u4f1a\u8bbe\u7f6e\u4e8b\u52a1\u4e3a\u8de8\u5206\u7247\u4e8b\u52a1\uff0c\u4ee5\u89e6\u53d1\u6b63\u5e38\u7684\u4e24\u9636\u6bb5\u63d0\u4ea4\u6d41\u7a0b\u3002COMMIT\u4f8b 2 \u7684\u91cd\u70b9\u5728\u4e8e\u5199\u4e86 2 \u4e2a\u5206\u7247\uff0c\u56e0\u6b64\u00a0COMMIT\u00a0\u65f6\u4f1a\u8c03\u7528\u00a0commitMultiShardTrx()\u00a0\u8d70\u591a\u5206\u7247\u7684\u5206\u5e03\u5f0f\u63d0\u4ea4\u6d41\u7a0b\u3002\u65b9\u6cd5\u00a0commitMultiShardTrx\u00a0\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ TsoTransaction#commitMultiShardTrx()<br \/>protected void commitMultiShardTrx() {<br \/>  \/\/ \u4e8b\u52a1\u65e5\u5fd7\u7684\u63d0\u4ea4\u72b6\u6001\uff0c\u4e00\u5171\u6709 3 \u79cd\uff1aFAILURE\uff0cUNKNODWN\uff0cSUCCESS\u3002<br \/>  TransactionCommitState commitState = TransactionCommitState.FAILURE;<br \/>  try {<\/p>\n<pre><code>\/\/ \u5bf9\u6240\u6709\u8fde\u63a5\u6267\u884c XA prepare\u3002\nprepareConnections();\n\/\/ \u62ff commit \u65f6\u95f4\u6233\u3002\ncommitTimestamp = nextTimestamp();\nConnection logConn = \/* \u83b7\u53d6\u4e3b\u5206\u7247\u4e0a\u7684\u8fde\u63a5 *\/;\n\/\/ \u6240\u6709\u5206\u652f\u4e8b\u52a1 prepare \u6210\u529f\uff0c\u5728\u5199\u4e8b\u52a1\u65e5\u5fd7\u524d\uff0c\u72b6\u6001\u8bbe\u7f6e\u4e3a UNKNOWN\uff0c\u5176\u4f5c\u7528\u89c1\u540e\u7eed\u4ee3\u7801\u8bf4\u660e\u3002\ncommitState = TransactionCommitState.UNKNOWN;\n\/\/ \u5199\u4e8b\u52a1\u65e5\u5fd7\u3002\nwriteCommitLog(logConn);\n\/\/ \u5199\u4e8b\u52a1\u65e5\u5fd7\u6210\u529f\uff0c\u72b6\u6001\u7f6e\u4e3a SUCCESS\u3002\ncommitState = TransactionCommitState.SUCCESS;<\/code><\/pre>\n<p>} catch (RuntimeException ex) {<\/p>\n<pre><code>exception = ex;<\/code><\/pre>\n<p>}<br \/>  if (commitState == TransactionCommitState.FAILURE) {<\/p>\n<pre><code>\/\/ \u5199\u4e8b\u52a1\u65e5\u5fd7\u524d\u5931\u8d25\u4e86\uff0c\u56de\u6eda\u6240\u6709\u8fde\u63a5\u3002\nrollbackConnections();<\/code><\/pre>\n<p>} else if (commitState == TransactionCommitState.SUCCESS) {<\/p>\n<pre><code>\/\/ \u5199\u4e8b\u52a1\u65e5\u5fd7\u6210\u529f\u4e86\uff0c\u63d0\u4ea4\u6240\u6709\u8fde\u63a5\u3002\ncommitConnections();<\/code><\/pre>\n<p>} else {<\/p>\n<pre><code>\/\/ \u6240\u6709\u8fde\u63a5\u90fd prepare \u6210\u529f\u4e86\uff0c\u4f46\u65e0\u6cd5\u786e\u5b9a\u662f\u5426\u5199\u5165\u4e86\u4e8b\u52a1\u65e5\u5fd7\uff0c\n\/\/ \u5c06\u7531\u4e8b\u52a1\u6062\u590d\u7684\u903b\u8f91\u6765\u51b3\u5b9a\u662f COMMIT \u8fd8\u662f ROLLBACK\u3002\u8fd9\u91cc\u5148\u4e22\u5f03\u6240\u6709\u8fde\u63a5\u3002\ndiscardConnections();<\/code><\/pre>\n<p>}<\/p>\n<p>\/\/ \u91ca\u653e\u5e76\u6e05\u7a7a\u8fd9\u4e9b\u7269\u7406\u8fde\u63a5\u3002<br \/>  connectionHolder.closeAllConnections();<\/p>\n<p>\/\/ prepare \u6216 commit \u9636\u6bb5\u629b\u51fa\u7684\u5f02\u5e38\uff0c\u8fd9\u91cc\u91cd\u65b0\u629b\u51fa\u3002<br \/>  if (exception != null) {<\/p>\n<pre><code>  throw exception;<\/code><\/pre>\n<p>}<br \/>}\u6298\u53e0 \u4e0a\u8ff0\u4ee3\u7801\u6b63\u662f\u4e24\u9636\u6bb5\u63d0\u4ea4\u7684\u6d41\u7a0b\u3002\u5728 prepare \u9636\u6bb5\uff0c\u8c03\u7528\u00a0prepareConnections()\uff0c\u5176\u4e2d\u5bf9\u53ea\u8bfb\u8fde\u63a5\u53ea\u662f\u7b80\u5355\u6267\u884c\u00a0ROLLBACK\u00a0\u8bed\u53e5\uff1b\u5bf9\u4e8e\u5199\u8fde\u63a5\uff0c\u6267\u884c\u00a0XA END {xid}\u00a0\u548c\u00a0XA PREPARE {xid}\u00a0\u8bed\u53e5\u3002\u5982\u679c\u6240\u6709\u8fde\u63a5\u90fd prepare \u6210\u529f\u4e86\uff0c\u5728 commit \u9636\u6bb5\uff0c\u8c03\u7528\u00a0writeCommitLog(logConn)\uff0c\u7528\u4e3b\u5206\u7247\uff08\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u4e2d\uff0c\u662f\u5206\u7247 1\uff09\u7684\u8fde\u63a5\uff0c\u5199\u4e0b\u4e8b\u52a1\u65e5\u5fd7\uff0c\u4e3b\u8981\u5305\u62ec\u4e86\u4e8b\u52a1\u7684 id \u548c commit \u65f6\u95f4\u6233\uff0c\u4e8b\u52a1\u65e5\u5fd7\u4e3b\u8981\u7528\u4e8e\u540e\u7eed\u7684\u4e8b\u52a1\u6062\u590d\u3002\u5982\u679c\u4e8b\u52a1\u65e5\u5fd7\u5199\u6210\u529f\u4e86\uff0c\u5c31\u610f\u5473\u7740 commit \u6210\u529f\u4e86\uff0c\u4f1a\u8c03\u7528\u00a0commitConnections()\u00a0\u5bf9\u6240\u6709\u8fde\u63a5\u8fdb\u884c\u63d0\u4ea4\uff0c\u8fd9\u4e00\u6b65\u53ea\u7528\u5bf9\u5199\u8fde\u63a5\u8bbe\u7f6e commit \u65f6\u95f4\u6233\u00a0SET innodb_commit_seq = {commitTimestamp}\u00a0\u548c\u6267\u884c\u00a0XA COMMIT {xid}\u00a0\u8bed\u53e5\u3002\u5982\u679c\u5728\u5199\u4e8b\u52a1\u65e5\u5fd7\u524d\u5931\u8d25\u4e86\uff0c\u4f1a\u8c03\u7528\u00a0rollbackConnections()\u00a0\u5bf9\u6240\u6709\u8fde\u63a5\u8fdb\u884c\u56de\u6eda\uff0c\u4e3b\u8981\u4f1a\u5bf9\u5199\u8fde\u63a5\u6267\u884c\u00a0XA ROLLBACK {xid}\u00a0\u56de\u6eda\u3002\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u662f\u5426\u6210\u529f\u5199\u5165\u4e86\u4e8b\u52a1\u65e5\u5fd7\uff0c\u4e8b\u52a1\u7684\u72b6\u6001\u4f1a\u662f UNKNOWN\u3002\u6b64\u65f6\uff0c\u6211\u4eec\u80fd\u786e\u5b9a\u6240\u6709\u5206\u652f\u4e8b\u52a1\u90fd\u6210\u529f prepare \u4e86\uff0c\u5982\u679c\u4e8b\u52a1\u65e5\u5fd7\u5199\u5165\u6210\u529f\u4e86\uff0c\u5219\u8981\u8fdb\u884c XA COMMIT\uff1b\u5982\u679c\u4e8b\u52a1\u65e5\u5fd7\u6ca1\u6709\u5199\u5165\uff0c\u5219\u8981\u8fdb\u884c XA ROLLBACK\u3002\u7531\u4e8e\u4e0d\u786e\u5b9a\u662f\u8981\u63d0\u4ea4\u8fd8\u662f\u56de\u6eda\uff0c\u6211\u4eec\u4f1a\u4e22\u5f03\u6240\u6709\u7269\u7406\u8fde\u63a5\uff0c\u4f7f\u8fd9\u4e9b\u8fde\u63a5\u540e\u7eed\u4e0d\u518d\u53ef\u7528\u3002\u81f3\u4e8e\u4e8b\u52a1\u6700\u7ec8\u662f\u63d0\u4ea4\u8fd8\u662f\u56de\u6eda\uff0c\u5219\u4ea4\u7ed9\u4e8b\u52a1\u6062\u590d\u7ebf\u7a0b\u6765\u5904\u7406\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u4f1a\u89e3\u8bfb\u4e8b\u52a1\u6062\u590d\u76f8\u5173\u7684\u4ee3\u7801\u3002\u4e8b\u52a1\u6062\u590d\u4e00\u4e2a\u5206\u5e03\u5f0f\u4e8b\u52a1\u5728\u63d0\u4ea4\u7684\u65f6\u5019\uff0c\u53ef\u80fd\u9047\u5230\u5404\u79cd\u60c5\u51b5\u5bfc\u81f4\u63d0\u4ea4\u5931\u8d25\u3002\u4f8b\u5982\uff0c\u6240\u6709\u5206\u652f\u4e8b\u52a1\u90fd prepare \u6210\u529f\u4e86\uff0c\u4e8b\u52a1\u65e5\u5fd7\u4e5f\u5199\u5165\u6210\u529f\u4e86\uff0c\u4f46 XA COMMIT \u5931\u8d25\u4e86\u3002\u5bf9\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4e8b\u52a1\u6062\u590d\u65f6\u9700\u8981\u6b63\u786e\u63d0\u4ea4\u6240\u6709\u5206\u652f\u4e8b\u52a1\u3002\u53e6\u4e00\u79cd\u60c5\u51b5\u662f\uff0c\u90e8\u5206\u5206\u652f\u4e8b\u52a1 prepare \u6210\u529f\u4e86\uff0c\u53e6\u5916\u4e00\u4e9b\u5931\u8d25\u4e86\uff0c\u6216\u4e8b\u52a1\u65e5\u5fd7\u6ca1\u6709\u5199\u5165\u6210\u529f\u3002\u5bf9\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4e8b\u52a1\u6062\u590d\u9700\u8981\u56de\u6eda\u6389\u5df2 prepare \u7684\u5206\u652f\u4e8b\u52a1\u3002\u4e8b\u52a1\u6062\u590d\u4e3b\u8981\u7531\u00a0XARecoverTask\u00a0\u8d1f\u8d23\u3002\u5176\u4e3b\u4f53\u4ee3\u7801\u4e3a\u00a0recoverInstance\u00a0\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u68c0\u67e5\u4e00\u4e2a DN \u4e0b\u7684\u6240\u6709 prepare \u8fc7\u7684\u4e8b\u52a1\uff0c\u5e76\u6839\u636e\u4e8b\u52a1\u72b6\u6001\u63d0\u4ea4\u6216\u56de\u6eda\u8fd9\u4e9b\u4e8b\u52a1\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ XARecoverTask#recoverInstance(IDataSource, Set&lt;String&gt;)<br \/>\/\/ dataSource \u7528\u6237\u83b7\u53d6 DN \u7684\u8fde\u63a5\uff0cgroups \u662f\u5f53\u524d\u903b\u8f91\u5e93\u7684\u6240\u6709\u7269\u7406\u5206\u7247<br \/>private void recoverInstance(IDataSource dataSource, Set&lt;String&gt; groups) {<br \/>  \/\/ \u6267\u884c XA RECOVER \u83b7\u53d6\u8be5 DN \u4e0a\u6240\u6709 prepare \u7684\u4e8b\u52a1\u3002<br \/>  \/\/ \u6b64\u5904\u7701\u7565\u4e86\u4ece dataSource \u83b7\u53d6\u8fde\u63a5\u548c\u751f\u6210 statement \u7684\u4ee3\u7801\u3002<br \/>  ResultSet rs = stmt.executeQuery(&#8220;XA RECOVER&#8221;);<br \/>  while (rs.next()) {<\/p>\n<pre><code>\/\/ \u5bf9\u6bcf\u4e00\u6761\u8bb0\u5f55\uff0c\u751f\u6210\u5bf9\u8c61 PreparedXATrans\uff0c\n\/\/ \u4e3b\u8981\u5305\u62ec xid\uff0c\u4e8b\u52a1id\uff0c\u5206\u652f\u4e8b\u52a1\u6240\u5728\u7684\u5206\u7247\uff0c\u4e3b\u5206\u7247\u7b49\u4fe1\u606f\u3002\nPreparedXATrans trans = \/* \u4ece rs \u4e2d\u83b7\u53d6\u4e00\u884c\u6570\u636e\u751f\u6210 *\/;\nif (\/* trans \u6240\u5728\u5206\u7247\u662f\u5f53\u524d\u903b\u8f91\u5e93\u7684\u4e00\u4e2a\u7269\u7406\u5206\u7247 &amp;&amp; \n    trans \u5728\u4e0a\u4e00\u6b21 recover \u4efb\u52a1\u65f6\u4e5f\u51fa\u73b0\u8fc7\uff0c\n    \u5373\u8f83\u957f\u65f6\u95f4\u90fd\u672a\u88ab\u63d0\u4ea4\u6216\u56de\u6eda*\/) {\n  \/\/ \u4ecb\u5165\u5904\u7406\u8fd9\u4e2a\u5206\u652f\u4e8b\u52a1\uff1a\u56de\u6eda\u6216\u63d0\u4ea4\u3002\n  rollBackOrForward(trans, stmt);\n}<\/code><\/pre>\n<p>}<br \/>}\u8be5\u4efb\u52a1\u6bcf 5 \u79d2\u5230\u6bcf\u4e2a DN \u4e0a\u6267\u884c\u4e00\u6b21\u00a0XA RECOVER\uff0c\u5f97\u5230\u6240\u6709 prepare \u8fc7\u7684\u4e8b\u52a1\uff0c\u5982\u679c\u770b\u5230\u4e00\u4e2a\u4e8b\u52a1\u5728\u4e0a\u4e00\u6b21\u4efb\u52a1\u4e2d\u4e5f\u51fa\u73b0\u8fc7\uff0c\u5373\u81f3\u5c11\u8fc7\u53bb 5 \u79d2\u90fd\u6ca1\u6709\u63d0\u4ea4\u6216\u56de\u6eda\uff0c\u5219\u4f1a\u9009\u62e9\u5bf9\u8fd9\u4e2a\u4e8b\u52a1\u8fdb\u884c\u56de\u6eda\u6216\u63d0\u4ea4\u3002\u76f8\u5173\u903b\u8f91\u4ee3\u7801\u4e3a\u00a0rollBackOrForward\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\/\/ XARecoverTask#rollBackOrForward(PreparedXATrans, Statement)<br \/>private boolean rollBackOrForward(PreparedXATrans trans, Statement stmt) throws SQLException {<br \/>  String primaryGroup = \/<em> \u4ece trans \u91cc\u89e3\u6790\u51fa\u4e3b\u5206\u7247\uff0c\u8be6\u89c1\u524d\u6587\u5173\u4e8e xid \u7684\u751f\u6210 <\/em>\/;<br \/>  \/\/ \u5c1d\u8bd5\u4ece\u4e3b\u5206\u7247\u7684\u4e8b\u52a1\u65e5\u5fd7\u4e2d\u627e\u5230\u76f8\u5173\u7684\u4e8b\u52a1\u65e5\u5fd7\u3002<br \/>  GlobalTxLog tx = GlobalTxLogManager.get(primaryGroup, trans.transId);<br \/>  if (tx != null) {<\/p>\n<pre><code>\/\/ \u786e\u5b9e\u5b58\u5728\u4e8b\u52a1\u65e5\u5fd7\uff0c\u6839\u636e\u4e8b\u52a1\u65e5\u5fd7\u72b6\u6001\u5224\u65ad\u56de\u6eda\u6216\u63d0\u4ea4\u3002\nif (tx.getState() == TransactionState.ABORTED) {\n  \/\/ ABORTED \u72b6\u6001\u7684\u4e8b\u52a1\u9700\u8981\u56de\u6eda\u3002\n  return tryRollback(stmt, trans);\n} else {\n  \/\/ SUCCESS \u72b6\u6001\u7684\u4e8b\u52a1\u9700\u8981\u63d0\u4ea4\u3002\n  return tryCommitTSO(stmt, trans, tx.getCommitTimestamp());\n}<\/code><\/pre>\n<p>} else {<\/p>\n<pre><code>\/\/ \u6ca1\u6709\u627e\u5230\u4e8b\u52a1\u65e5\u5fd7\uff0c\u5c1d\u8bd5\u56de\u6eda\uff0c\u5148\u5f00\u542f\u4e8b\u52a1\uff0c\u5199\u4e0b\u4e8b\u52a1\u65e5\u5fd7\uff0c\u6807\u8bb0\u4e8b\u52a1\u4e3a ABORTED\u3002\ntry (Connection conn2 = \/* \u83b7\u53d6\u4e3b\u5206\u7247\u4e0a\u7684\u53e6\u4e00\u4e2a\u8fde\u63a5 *\/;) {\n  conn2.setAutocommit(false);\n  \/\/ \u5c1d\u8bd5\u56de\u6eda\uff0c\u5982\u679c\u56e0\u4e3a\u522b\u7684\u7ebf\u7a0b\u6b63\u5728\u5904\u7406\u8fd9\u4e2a\u4e8b\u52a1\n  \/\/\uff08\u6bd4\u5982\u8be5\u4e8b\u52a1\u53ea\u662f\u63d0\u4ea4\u5f97\u6162\uff0c\u8fde\u63a5\u4ecd\u672a\u65ad\u5f00\uff0c\u8fd8\u5728\u63d0\u4ea4\u6d41\u7a0b\uff09\n  \/\/ \u800c\u62a5\u9519\uff0c\u5c31\u56de\u6eda\u4e0a\u4e00\u6761\u5199\u4e8b\u52a1\u65e5\u5fd7\u7684\u8bed\u53e5\u3002\n  txLog.append(transInfo.transId, TransactionType.XA, TransactionState.ABORTED, new ConnectionContext(), conn2);\n  stmt.execute(&quot;XA ROLLBACK &quot; + trans.toXid());\n  conn2.commit();\n  return true;\n} catch (Exception e) {\n  \/* \u6839\u636e\u5f02\u5e38\u5224\u65ad\u662f\u5426\u8981\u56de\u6eda\u5199\u4e8b\u52a1\u65e5\u5fd7\u7684\u64cd\u4f5c *\/\n}<\/code><\/pre>\n<p>}<br \/>}\u8be5\u65b9\u6cd5\u4e3b\u8981\u6709 3 \u6bb5\u903b\u8f91\u3002\u4e00\u662f\u5982\u679c\u5b58\u5728\u5bf9\u5e94\u7684\u4e8b\u52a1\u65e5\u5fd7\uff0c\u4e14\u4e8b\u52a1\u72b6\u6001\u662f ABORTED\uff0c\u90a3\u5c31\u6267\u884c\u00a0tryRollback\u00a0\u65b9\u6cd5\u56de\u6eda\uff0c\u8be5\u65b9\u6cd5\u4e3b\u8981\u6267\u884c\u4e86\u00a0XA ROLLBACK {xid}\u3002\u4e8c\u662f\u5982\u679c\u4e8b\u52a1\u72b6\u6001\u662f SUCCESS\uff0c\u90a3\u5c31\u6267\u884c\u00a0tryCommitTSO\u00a0\u65b9\u6cd5\u56de\u6eda\uff0c\u8be5\u65b9\u6cd5\u4f1a\u8bbe\u7f6e commit \u65f6\u95f4\u6233\uff0c\u7136\u540e\u6267\u884c\u00a0XA COMMIT {xid}\u3002\u4e09\u662f\u5982\u679c\u6ca1\u627e\u5230\u4e8b\u52a1\u65e5\u5fd7\uff0c\u6b64\u65f6\u4e00\u822c\u6709\u4e24\u79cd\u53ef\u80fd\uff1a1\uff09\u4e8b\u52a1\u63d0\u4ea4\u5931\u8d25\u4e86\uff0c\u4e14\u6ca1\u5199\u4e0b\u4e8b\u52a1\u65e5\u5fd7\uff0c\u6b64\u65f6\u9700\u8981\u56de\u6eda\uff1b2\uff09\u4e8b\u52a1\u8fd8\u5728\u4e24\u9636\u6bb5\u63d0\u4ea4\u7684\u6d41\u7a0b\u4e2d\uff0c\u53ea\u662f prepare \u8f83\u6162\uff0c\u8fd8\u6ca1\u5f00\u59cb\u5199\u4e8b\u52a1\u65e5\u5fd7\uff0c\u6b64\u65f6\u4e0d\u9700\u8981\u505a\u4efb\u4f55\u64cd\u4f5c\u3002\u5728 MySQL \u4e2d\uff0c\u5982\u679c\u53d1\u8d77\u00a0XA START\u00a0\u7684\u8fde\u63a5\u6ca1\u6709\u5173\u95ed\uff0c\u5176\u4ed6\u8fde\u63a5\u662f\u65e0\u6cd5\u901a\u8fc7\u00a0XA ROLLBACK\u00a0\u6216\u00a0XA COMMIT\u00a0\u6765\u56de\u6eda\u6216\u63d0\u4ea4\u8fd9\u4e2a\u5206\u652f\u4e8b\u52a1\u7684\u3002\u6211\u4eec\u5229\u7528\u8fd9\u4e00\u7279\u6027\uff0c\u9996\u5148\u5728\u4e8b\u52a1\u65e5\u5fd7\u63d2\u5165\u4e00\u6761 ABORTED \u8bb0\u5f55\uff0c\u8868\u660e\u8fd9\u4e2a\u5206\u5e03\u5f0f\u4e8b\u52a1\u9700\u8981\u56de\u6eda\uff0c\u7136\u540e\u5c1d\u8bd5\u6267\u884c\u00a0XA ROLLBACK\u00a0\u56de\u6eda\u8fd9\u4e2a\u5206\u652f\u4e8b\u52a1\u3002\u5982\u679c\u9047\u5230 2\uff09\u7684\u60c5\u51b5\uff0c\u5219\u4f1a\u6536\u5230\u7279\u5b9a\u7684\u62a5\u9519\uff0c\u6b64\u65f6\u518d\u56de\u6eda\u6389\u63d2\u5165 ABORTED \u4e8b\u52a1\u65e5\u5fd7\u7684\u64cd\u4f5c\u3002\u5728\u6211\u4eec\u63d2\u5165 ABORTED \u4e8b\u52a1\u65e5\u5fd7\u540e\uff0c\u539f\u672c\u6b63\u5728\u63d0\u4ea4\u4e8b\u52a1\u7684\u7ebf\u7a0b\u5728\u63d2\u5165 SUCCESS \u4e8b\u52a1\u65e5\u5fd7\u65f6\u4f1a\u88ab\u963b\u585e\uff0c\u800c\u5728\u6211\u4eec\u56de\u6eda\u6389\u63d2\u5165 ABORTED \u4e8b\u52a1\u65e5\u5fd7\u7684\u64cd\u4f5c\u540e\uff0c\u4e8b\u52a1\u63d0\u4ea4\u6d41\u7a0b\u5c31\u4f1a\u7ee7\u7eed\u8fdb\u884c\u4e0b\u53bb\u3002\u5c0f\u7ed3\u672c\u6587\u4e3b\u8981\u89e3\u8bfb\u4e86 PolarDB-X \u4e2d CN \u7aef\u7684\u4e8b\u52a1\u76f8\u5173\u7684\u4ee3\u7801\uff0c\u4ee5 TSO \u4e8b\u52a1\u4e3a\u4e3b\uff0c\u4f7f\u7528\u4e24\u4e2a\u4f8b\u5b50\uff0c\u4e00\u6b65\u6b65\u5730\u5c55\u793a\u4e86\u4e8b\u52a1\u7684\u5f00\u542f\u3001\u6267\u884c\u3001\u63d0\u4ea4\u3001\u6062\u590d\u7b49\u6d41\u7a0b\u3002\u5e0c\u671b\u5927\u5bb6\u9605\u8bfb\u672c\u6587\u540e\uff0c\u80fd\u66f4\u52a0\u4e86\u89e3 PolarDB-X \u7684\u4e8b\u52a1\u7cfb\u7edf\u3002\u539f\u6587\u94fe\u63a5\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=r%2BpKjEAoiXtQeC1NksvDrA%3D%3D.AgGx7GJpC3OhnZvTJRbbW6A%2FoK9W2jIOzSQK21X3S9wPX068ceR2sRSyIi1fgnnM\" rel=\"nofollow\">http:\/\/click.aliyun.com\/m\/100&#8230;<\/a>\u672c\u6587\u4e3a\u963f\u91cc\u4e91\u539f\u521b\u5185\u5bb9\uff0c\u672a\u7ecf\u5141\u8bb8\u4e0d\u5f97\u8f6c\u8f7d\u3002<\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042237271\">https:\/\/segmentfault.com\/a\/1190000042237271<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u4ecb\uff1a\u00a0\u672c\u6587\u5c06\u4e3b\u8981\u89e3\u8bfb PolarDB-X \u4e2d\u4e8b\u52a1\u90e8\u5206\u7684\u76f8\u5173\u4ee3\u7801\uff0c\u7740\u91cd\u89e3\u8bfb\u4e8b\u52a1\u7684\u4e00\u751f\u5728\u8ba1\u7b97\u8282\u70b9\uff08CN\uff09\u4e2d\u7684\u5173\u952e [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10006040","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10006040"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006040\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}