ITPub博客

首页 > 应用开发 > Java > 同步写两个数据库

同步写两个数据库

原创 Java 作者:壹頁書 时间:2016-06-12 16:44:08 0 删除 编辑
两个数据库假设在不同的服务器,不同的实例.
  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博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-2119080/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 参加Gdevops总结
请登录后发表评论 登录
全部评论

注册时间:2013-10-19

  • 博文量
    620
  • 访问量
    6339945