Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / алгоритм работы с распределенными транзакциями / 25 сообщений из 25, страница 1 из 1
31.03.2017, 14:27
    #39430921
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Помогите, как реализовать правильный алгоритм
Исходные
переделываем систему на двухфазную фиксацию
java se, 2 oracle db (локальная и удаленная).
Нужно реализовать циклическую выгрузку из одной базы в другую.
В качестве прототипа работы транзакциями - вот этот пример

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
// You need to import the java.sql package to use JDBC
import java.sql.*;
import javax.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.*;
import oracle.jdbc.xa.OracleXid;
import oracle.jdbc.xa.OracleXAException;
import oracle.jdbc.xa.client.*;
import javax.transaction.xa.*;

class XA4
{
  public static void main (String args [])
       throws SQLException 
  {

    try
    {
        String URL1 = "jdbc:oracle:oci:@";
        // You can put a database name after the @ sign in the connection URL.
        String URL2 ="jdbc:oracle:thin:@(description=(address=(host=localhost)
                     (protocol=tcp)(port=5521))(connect_data=(service_name=orcl)))";
        // Create first DataSource and get connection
        OracleDataSource ods1 = new OracleDataSource();
        ods1.setURL(URL1);
        ods1.setUser("HR");
        ods1.setPassword("hr");
        Connection conna = ods1.getConnection();

        // Create second DataSource and get connection
        OracleDataSource ods2 = new OracleDataSource();
        ods2.setURL(URL2);
        ods2.setUser("HR");
        ods2.setPassword("hr");
        Connection connb = ods2.getConnection();

        // Prepare a statement to create the table
        Statement stmta = conna.createStatement ();

        // Prepare a statement to create the table
        Statement stmtb = connb.createStatement ();

        try
        {
          // Drop the test table
          stmta.execute ("drop table my_table");
        }
        catch (SQLException e)
        {
          // Ignore an error here
        }

        try
        {   
          // Create a test table
          stmta.execute ("create table my_table (col1 int)");
        }
        catch (SQLException e)
        {
          // Ignore an error here too
        }

        try
        {
          // Drop the test table
          stmtb.execute ("drop table my_tab");
        }
        catch (SQLException e)
        {
          // Ignore an error here
        }

        try
        {   
          // Create a test table
          stmtb.execute ("create table my_tab (col1 char(30))");
        }
        catch (SQLException e)
        {
          // Ignore an error here too
        }

        // Create XADataSource instances and set properties.
        OracleXADataSource oxds1 = new OracleXADataSource();
        oxds1.setURL("jdbc:oracle:oci:@");
        oxds1.setUser("HR");
        oxds1.setPassword("hr");

        OracleXADataSource oxds2 = new OracleXADataSource();

        oxds2.setURL("jdbc:oracle:thin:@(description=(address=(host=localhost)
                   (protocol=tcp)(port=5521))(connect_data=(service_name=orcl)))");
        oxds2.setUser("HR");
        oxds2.setPassword("hr");
    
        // Get XA connections to the underlying data sources
        XAConnection pc1  = oxds1.getXAConnection();
        XAConnection pc2  = oxds2.getXAConnection();

        // Get the physical connections
        Connection conn1 = pc1.getConnection();
        Connection conn2 = pc2.getConnection();

        // Get the XA resources
        XAResource oxar1 = pc1.getXAResource();
        XAResource oxar2 = pc2.getXAResource();

        // Create the Xids With the Same Global Ids
        Xid xid1 = createXid(1);
        Xid xid2 = createXid(2);

        // Start the Resources
        oxar1.start (xid1, XAResource.TMNOFLAGS);
        oxar2.start (xid2, XAResource.TMNOFLAGS);

        // Execute SQL operations with conn1 and conn2
        doSomeWork1 (conn1);
        doSomeWork2 (conn2);

        // END both the branches -- IMPORTANT
        oxar1.end(xid1, XAResource.TMSUCCESS);
        oxar2.end(xid2, XAResource.TMSUCCESS);

        // Prepare the RMs
        int prp1 =  oxar1.prepare (xid1);
        int prp2 =  oxar2.prepare (xid2);

        System.out.println("Return value of prepare 1 is " + prp1);
        System.out.println("Return value of prepare 2 is " + prp2);

        boolean do_commit = true;

        if (!((prp1 == XAResource.XA_OK) || (prp1 == XAResource.XA_RDONLY)))
           do_commit = false;

        if (!((prp2 == XAResource.XA_OK) || (prp2 == XAResource.XA_RDONLY)))
           do_commit = false;

       System.out.println("do_commit is " + do_commit);
        System.out.println("Is oxar1 same as oxar2 ? " + oxar1.isSameRM(oxar2));

        if (prp1 == XAResource.XA_OK)
          if (do_commit)
             oxar1.commit (xid1, false);
          else
             oxar1.rollback (xid1);

        if (prp2 == XAResource.XA_OK)
          if (do_commit)
             oxar2.commit (xid2, false);
          else
             oxar2.rollback (xid2);

         // Close connections
        conn1.close();
        conn1 = null;
        conn2.close();
        conn2 = null;

        pc1.close();
        pc1 = null;
        pc2.close();
        pc2 = null;

        ResultSet rset = stmta.executeQuery ("select col1 from my_table");
        while (rset.next())
          System.out.println("Col1 is " + rset.getInt(1));
  
        rset.close();
        rset = null;

        rset = stmtb.executeQuery ("select col1 from my_tab");
        while (rset.next())
          System.out.println("Col1 is " + rset.getString(1));
  
        rset.close();
        rset = null;

        stmta.close();
        stmta = null;
        stmtb.close();
        stmtb = null;

        conna.close();
        conna = null;
        connb.close();
        connb = null;

    } catch (SQLException sqe)
    {
      sqe.printStackTrace();
    } catch (XAException xae)
    {
      if (xae instanceof OracleXAException) {
        System.out.println("XA Error is " +
                      ((OracleXAException)xae).getXAError());
        System.out.println("SQL Error is " +
                      ((OracleXAException)xae).getOracleError());
      }
    }
  }

  static Xid createXid(int bids)
    throws XAException
  {...Create transaction IDs...}

  private static void doSomeWork1 (Connection conn)
   throws SQLException
  {...Execute SQL operations...}

  private static void doSomeWork2 (Connection conn)
   throws SQLException
  {...Execute SQL operations...}
}



Логика приложения
1. читаем в цикле курсором READONLY данные из таблицы источника в удаленной базе
2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
3. блокируем (select for update) обрабатываемую запись в таблице источнике в удаленной базе
4. в локальной базе создаем savepoint.
5. раскладываем данные по нескольким таблицам с локальной базе (INSERT, UPDATE, MERGE)
6. если в процессе записи в локальной базе есть логические ошибки, откатываемся до savepoint, и пишем данный в промежуточные таблицы для дальнейшего разбора.
7. пишем логи в удаленной базе и меняем статусы
8. commit
9. крутим цикл

Вопросы
1. будет ли работать rollback to savepoint в XA реализации
2. так как точка фиксации транзакции внутри курсора, достаточно ли будет 2-х коннектов к базам данных,
или 2 к одной и 1 к другой ?
3. правильно ли я понимаю, что начало транзакции - это
// Start the Resources
oxar1.start (xid1, XAResource.TMNOFLAGS);

4. что является окончанием транзакции ? Завершением работы с ресурсом или commit/rollback?


oxar1.end(xid1, XAResource.TMSUCCESS);

или

if (prp1 == XAResource.XA_OK)
if (do_commit)
oxar1.commit (xid1, false);
else
oxar1.rollback (xid1);


«Никогда не поздно стать тем, кем ты мог бы быть».
...
Рейтинг: 0 / 0
31.03.2017, 15:15
    #39430974
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
А зачем руками всё делать?
https://www.atomikos.com/
...
Рейтинг: 0 / 0
31.03.2017, 15:27
    #39430983
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
А есть примеры внедрения этого решения в существующую систему?
...
Рейтинг: 0 / 0
31.03.2017, 15:32
    #39430987
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Раздел samples на этом ресурсе не открывается. Не могу оценить.
...
Рейтинг: 0 / 0
31.03.2017, 16:20
    #39431026
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmac,
Savepoint тут не нужен. Достаточно begin tran.
Ну и репликацию зачем забыли?
...
Рейтинг: 0 / 0
31.03.2017, 16:28
    #39431034
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
как без savepoint откатиться до предыдущего состояния данных ?
репликацию ? При чем здесь репликация ?
...
Рейтинг: 0 / 0
31.03.2017, 16:35
    #39431040
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmac,
Откат транзакции вернет на начало.
Точки для много точек.
...
Рейтинг: 0 / 0
31.03.2017, 16:44
    #39431053
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Petro123,

возможно я не полностью описал логику, до rollback to savepoint выполняется dml, который не нужно откатывать.
откатываем только часть транзакции.
...
Рейтинг: 0 / 0
31.03.2017, 16:45
    #39431054
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Распределенные это две пишущие. У тебя одна.
...
Рейтинг: 0 / 0
31.03.2017, 16:46
    #39431055
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmac,

Ну да. Описал ты Решение. А нужно задачу.
...
Рейтинг: 0 / 0
31.03.2017, 16:50
    #39431061
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Petro123,
У меня 2 пишущих.

Задача - модифицировать наше приложение, с учетом поддержки XA транзакций.
Упрощенный алгоритм работы компоненты приложения привел.
...
Рейтинг: 0 / 0
31.03.2017, 17:01
    #39431065
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmac2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
а почему он может быть запрещён, если оракл не блокировочник?
...
Рейтинг: 0 / 0
31.03.2017, 17:03
    #39431067
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Бизнес выставляет запрет вноса изменения в базу. Вообще это к делу не относится.
...
Рейтинг: 0 / 0
31.03.2017, 17:03
    #39431068
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacрепликацию ? При чем здесь репликация ?
вдруг вы не в курсе что это:
blackmacНужно реализовать циклическую выгрузку из одной базы в другую.
оракл умеет сам. Только IP другой БД укажи. И старше XE должен быть.
...
Рейтинг: 0 / 0
31.03.2017, 17:04
    #39431069
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacБизнес выставляет запрет вноса изменения в базу.
так и говори. Относится. Пусть будет так - они ставят палки в колёса))).
Будем обрабатывать).
...
Рейтинг: 0 / 0
31.03.2017, 17:14
    #39431077
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacБизнес выставляет запрет вноса изменения в базу. Вообще это к делу не относится.
подумал.
Всё равно не выходит.
Надо их послать подальше).
Вот это:
автор2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
не будет означать что бизнес разрешил т.к. ты раскидываешь потом вставку. Т.е. ты блокировкой проверил таблицуА и ЗАПИСЬ1234. А работать будешь с MERGE\INSERT.
Т.е. с совершенно другими объектами.
Пусть придумают другой флаг.
...
Рейтинг: 0 / 0
31.03.2017, 17:25
    #39431080
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacдо rollback to savepoint выполняется dml, который не нужно откатывать.
откатываем только часть транзакции.
нифига себе.
Ты страшные слова не пиши. DML это обычные insert\update.
Только что тут не надо откатывать?
Автономные транзакции логирования?
...
Рейтинг: 0 / 0
31.03.2017, 17:32
    #39431082
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmac2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
3. блокируем (select for update) обрабатываемую запись в таблице источнике в удаленной базе
т.е. представляешь, ты в цикле на лимон записей будешь ставить блокировку в обе базы внутри цикла FOR{
.......
Ну и не вижу пока распределённой ВТОРОЙ транзакции WRITE на ВТОРОЙ сервер.
IMHO
...
Рейтинг: 0 / 0
31.03.2017, 17:45
    #39431091
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Petro123,
5 и 6 - write в одной базе данных
7 - write в другой базе данных
...
Рейтинг: 0 / 0
31.03.2017, 17:51
    #39431095
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacPetro123,
5 и 6 - write в одной базе данных
7 - write в другой базе данных
а если так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
for cursor // прочли запись
   if local.естьРазрешение(cursor.id) {
        local.BEGIN TRAN
           пишем в локальную
           пишем логи и флаги
        local.COMMIT
   }
}
...
Рейтинг: 0 / 0
31.03.2017, 17:55
    #39431099
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
Petro123,
Подразумевается что это транзакция в одной из баз данных ?
А где управление транзакцией в другой базе ?
...
Рейтинг: 0 / 0
31.03.2017, 18:05
    #39431105
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
blackmacА где управление транзакцией в другой базе ?
так?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
for cursor // прочли запись
   if local.естьРазрешение(cursor.id) {
        local.BEGIN TRAN
           local.Write()
           server_ip.WriteLog()
        local.COMMIT
   }
}
...
Рейтинг: 0 / 0
31.03.2017, 18:17
    #39431111
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
в моём примере тоги лог-флаг в пишущей второй. Это можно и без распределённой.
Вот если бы ты удалял (перенос) объектов - тогда Да! Распределённая в чистом виде.
imho
...
Рейтинг: 0 / 0
31.03.2017, 18:24
    #39431114
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
окапечатка
Petro123в моём примере тоги лог-флаг в пишущей второй.
во второй пишущей только ставим логи-флаг-галку.
...
Рейтинг: 0 / 0
31.03.2017, 19:18
    #39431133
blackmac
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
алгоритм работы с распределенными транзакциями
ок.
пофлудили, теперь по моим вопросам предметно.
1. savepoint не создается
невозможно задать точку отката в активной глобальной транзакции.
Есть workaround?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / алгоритм работы с распределенными транзакциями / 25 сообщений из 25, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]