powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / алгоритм работы с распределенными транзакциями
25 сообщений из 25, страница 1 из 1
алгоритм работы с распределенными транзакциями
    #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
алгоритм работы с распределенными транзакциями
    #39430974
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем руками всё делать?
https://www.atomikos.com/
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39430983
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А есть примеры внедрения этого решения в существующую систему?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39430987
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раздел samples на этом ресурсе не открывается. Не могу оценить.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431026
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmac,
Savepoint тут не нужен. Достаточно begin tran.
Ну и репликацию зачем забыли?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431034
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как без savepoint откатиться до предыдущего состояния данных ?
репликацию ? При чем здесь репликация ?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431040
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmac,
Откат транзакции вернет на начало.
Точки для много точек.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431053
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,

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

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

Задача - модифицировать наше приложение, с учетом поддержки XA транзакций.
Упрощенный алгоритм работы компоненты приложения привел.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431065
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmac2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
а почему он может быть запрещён, если оракл не блокировочник?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431067
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бизнес выставляет запрет вноса изменения в базу. Вообще это к делу не относится.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431068
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmacрепликацию ? При чем здесь репликация ?
вдруг вы не в курсе что это:
blackmacНужно реализовать циклическую выгрузку из одной базы в другую.
оракл умеет сам. Только IP другой БД укажи. И старше XE должен быть.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431069
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmacБизнес выставляет запрет вноса изменения в базу.
так и говори. Относится. Пусть будет так - они ставят палки в колёса))).
Будем обрабатывать).
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431077
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmacБизнес выставляет запрет вноса изменения в базу. Вообще это к делу не относится.
подумал.
Всё равно не выходит.
Надо их послать подальше).
Вот это:
автор2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
не будет означать что бизнес разрешил т.к. ты раскидываешь потом вставку. Т.е. ты блокировкой проверил таблицуА и ЗАПИСЬ1234. А работать будешь с MERGE\INSERT.
Т.е. с совершенно другими объектами.
Пусть придумают другой флаг.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431080
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmacдо rollback to savepoint выполняется dml, который не нужно откатывать.
откатываем только часть транзакции.
нифига себе.
Ты страшные слова не пиши. DML это обычные insert\update.
Только что тут не надо откатывать?
Автономные транзакции логирования?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431082
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blackmac2. проверяем (select READONLY) что в локальной базе разрешен процесс вставки
3. блокируем (select for update) обрабатываемую запись в таблице источнике в удаленной базе
т.е. представляешь, ты в цикле на лимон записей будешь ставить блокировку в обе базы внутри цикла FOR{
.......
Ну и не вижу пока распределённой ВТОРОЙ транзакции WRITE на ВТОРОЙ сервер.
IMHO
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431091
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,
5 и 6 - write в одной базе данных
7 - write в другой базе данных
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #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
алгоритм работы с распределенными транзакциями
    #39431099
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,
Подразумевается что это транзакция в одной из баз данных ?
А где управление транзакцией в другой базе ?
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #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
алгоритм работы с распределенными транзакциями
    #39431111
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в моём примере тоги лог-флаг в пишущей второй. Это можно и без распределённой.
Вот если бы ты удалял (перенос) объектов - тогда Да! Распределённая в чистом виде.
imho
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431114
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
окапечатка
Petro123в моём примере тоги лог-флаг в пишущей второй.
во второй пишущей только ставим логи-флаг-галку.
...
Рейтинг: 0 / 0
алгоритм работы с распределенными транзакциями
    #39431133
blackmac
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ок.
пофлудили, теперь по моим вопросам предметно.
1. savepoint не создается
невозможно задать точку отката в активной глобальной транзакции.
Есть workaround?
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / алгоритм работы с распределенными транзакциями
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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