同步寫兩個資料庫

壹頁書發表於2016-06-12
兩個資料庫假設在不同的伺服器,不同的例項.
  1. drop database db1;  
  2. drop database db2;  
  3. create database db1;  
  4. use db1;  
  5. create table t(translog int primary key,ts timestamp default current_timestamp);  
  6.   
  7. create database db2;  
  8. use db2;  
  9. create table t(translog int primary key,ts timestamp default current_timestamp);  
  10. insert into t(translog) values(10); 

db2的t表,增加一個tid為10的資料

一般應用程式,先寫一個庫提交,然後再寫一個庫.
假如第二個庫事務失敗,則事務補償第一個庫.

避免分散式事務是架構設計的重點.
可以採用如下的方式,減小不一致發生的機率.

  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.PreparedStatement;  
  4. import java.sql.SQLException;  
  5.   
  6. public class Test {  
  7.   
  8.     private synchronized static Connection getConnection(String dbName) {  
  9.         String URL = "jdbc:mysql://127.0.0.1:3306/" + dbName;  
  10.         String USERNAME = "xx";  
  11.         String PWD = "xx";  
  12.         Connection con = null;  
  13.         try {  
  14.             Class.forName("com.mysql.jdbc.Driver");  
  15.             con = DriverManager.getConnection(URL, USERNAME, PWD);  
  16.             con.setAutoCommit(false);  
  17.         } catch (SQLException e) {  
  18.         } catch (ClassNotFoundException e) {  
  19.         }  
  20.         return con;  
  21.     }  
  22.   
  23.     public void insertDB(Connection con, int translogid) throws SQLException {  
  24.   
  25.         PreparedStatement pt;  
  26.         pt = con.prepareStatement("insert into t(translog) values(?)");  
  27.         pt.setInt(1, translogid);  
  28.         pt.execute();  
  29.   
  30.     }  
  31.   
  32.     public void insertTranslogid(int translogid) {  
  33.         Connection db1 = getConnection("db1");  
  34.         Connection db2 = getConnection("db2");  
  35.         try {  
  36.             insertDB(db1, translogid);  
  37.             insertDB(db2, translogid);  
  38.         } catch (SQLException e) {  
  39.             e.printStackTrace();  
  40.             try {  
  41.                 db1.rollback();  
  42.                 db2.rollback();  
  43.                 db1.close();  
  44.                 db2.close();  
  45.                 return;  
  46.             } catch (SQLException ex) {  
  47.                 ex.printStackTrace();  
  48.                 return;  
  49.             }  
  50.         }  
  51.   
  52.         try {  
  53.             db1.commit();  
  54.             db2.commit();  
  55.             db1.close();  
  56.             db2.close();  
  57.         } catch (SQLException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61.   
  62.     public static void main(String[] args) throws ClassNotFoundException, SQLException {  
  63.         Test t = new Test();  
  64.         for (int i = 0; i <= 10; i++) {  
  65.             t.insertTranslogid(i);  
  66.         }  
  67.     }  
  68. }  


先執行寫db1,但是並不提交.接著寫db2.
如果寫兩個庫,都沒有發生異常.則一起提交.否則一起回滾.

執行上述程式,在translogid為10的時候,db2有主鍵衝突的異常.db1會回滾已經寫入的資料.

這個模式有一個缺點.
db1的鎖持有時間和連線持有時間,增加了一倍.因為他要等待db2的處理結果.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-2119080/,如需轉載,請註明出處,否則將追究法律責任。

相關文章