示例:重新执行应用SQL

当主数据库节点故障且10s未恢复时,openGauss会将对应的备数据库节点升主,使openGauss正常运行。备升主期间正在运行的作业会失败;备升主后启动的作业不会再受影响。如果要做到数据库节点主备切换过程中,上层业务不感知,可参考此示例构建业务层SQL重试机制。

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. class ExitHandler extends Thread {
  8. private Statement cancel_stmt = null;
  9. public ExitHandler(Statement stmt) {
  10. super("Exit Handler");
  11. this.cancel_stmt = stmt;
  12. }
  13. public void run() {
  14. System.out.println("exit handle");
  15. try {
  16. this.cancel_stmt.cancel();
  17. } catch (SQLException e) {
  18. System.out.println("cancel query failed.");
  19. e.printStackTrace();
  20. }
  21. }
  22. }
  23. public class SQLRetry {
  24. //创建数据库连接。
  25. public static Connection GetConnection(String username, String passwd) {
  26. String driver = "org.postgresql.Driver";
  27. String sourceURL = "jdbc:postgresql://10.131.72.136:8000/postgres";
  28. Connection conn = null;
  29. try {
  30. //加载数据库驱动。
  31. Class.forName(driver).newInstance();
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. return null;
  35. }
  36. try {
  37. //创建数据库连接。
  38. conn = DriverManager.getConnection(sourceURL, username, passwd);
  39. System.out.println("Connection succeed!");
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. return null;
  43. }
  44. return conn;
  45. }
  46. //执行普通SQL语句,创建jdbc_test1表。
  47. public static void CreateTable(Connection conn) {
  48. Statement stmt = null;
  49. try {
  50. stmt = conn.createStatement();
  51. Runtime.getRuntime().addShutdownHook(new ExitHandler(stmt));
  52. //执行普通SQL语句。
  53. int rc2 = stmt
  54. .executeUpdate("DROP TABLE if exists jdbc_test1;");
  55. int rc1 = stmt
  56. .executeUpdate("CREATE TABLE jdbc_test1(col1 INTEGER, col2 VARCHAR(10));");
  57. stmt.close();
  58. } catch (SQLException e) {
  59. if (stmt != null) {
  60. try {
  61. stmt.close();
  62. } catch (SQLException e1) {
  63. e1.printStackTrace();
  64. }
  65. }
  66. e.printStackTrace();
  67. }
  68. }
  69. //执行预处理语句,批量插入数据。
  70. public static void BatchInsertData(Connection conn) {
  71. PreparedStatement pst = null;
  72. try {
  73. //生成预处理语句。
  74. pst = conn.prepareStatement("INSERT INTO jdbc_test1 VALUES (?,?)");
  75. for (int i = 0; i < 100; i++) {
  76. //添加参数。
  77. pst.setInt(1, i);
  78. pst.setString(2, "data " + i);
  79. pst.addBatch();
  80. }
  81. //执行批处理。
  82. pst.executeBatch();
  83. pst.close();
  84. } catch (SQLException e) {
  85. if (pst != null) {
  86. try {
  87. pst.close();
  88. } catch (SQLException e1) {
  89. e1.printStackTrace();
  90. }
  91. }
  92. e.printStackTrace();
  93. }
  94. }
  95. //执行预编译语句,更新数据。
  96. private static boolean QueryRedo(Connection conn){
  97. PreparedStatement pstmt = null;
  98. boolean retValue = false;
  99. try {
  100. pstmt = conn
  101. .prepareStatement("SELECT col1 FROM jdbc_test1 WHERE col2 = ?");
  102. pstmt.setString(1, "data 10");
  103. ResultSet rs = pstmt.executeQuery();
  104. while (rs.next()) {
  105. System.out.println("col1 = " + rs.getString("col1"));
  106. }
  107. rs.close();
  108. pstmt.close();
  109. retValue = true;
  110. } catch (SQLException e) {
  111. System.out.println("catch...... retValue " + retValue);
  112. if (pstmt != null) {
  113. try {
  114. pstmt.close();
  115. } catch (SQLException e1) {
  116. e1.printStackTrace();
  117. }
  118. }
  119. e.printStackTrace();
  120. }
  121. System.out.println("finesh......");
  122. return retValue;
  123. }
  124. //查询语句,执行失败重试,重试次数可配置。
  125. public static void ExecPreparedSQL(Connection conn) throws InterruptedException {
  126. int maxRetryTime = 50;
  127. int time = 0;
  128. String result = null;
  129. do {
  130. time++;
  131. try {
  132. System.out.println("time:" + time);
  133. boolean ret = QueryRedo(conn);
  134. if(ret == false){
  135. System.out.println("retry, time:" + time);
  136. Thread.sleep(10000);
  137. QueryRedo(conn);
  138. }
  139. } catch (Exception e) {
  140. e.printStackTrace();
  141. }
  142. } while (null == result && time < maxRetryTime);
  143. }
  144. /**
  145. * 主程序,逐步调用各静态方法。
  146. * @param args
  147. * @throws InterruptedException
  148. */
  149. public static void main(String[] args) throws InterruptedException {
  150. //创建数据库连接。
  151. Connection conn = GetConnection("testuser", "test@123");
  152. //创建表。
  153. CreateTable(conn);
  154. //批插数据。
  155. BatchInsertData(conn);
  156. //执行预编译语句,更新数据。
  157. ExecPreparedSQL(conn);
  158. //关闭数据库连接。
  159. try {
  160. conn.close();
  161. } catch (SQLException e) {
  162. e.printStackTrace();
  163. }
  164. }
  165. }