привет, я портирую приложение wbsphere на tomcat, мне нужно работать над двумя базами данных на одном сервере, и я интегрировал tomcat с существенной транзакцией atomikos.Это мой первый проект с jta, и оракул dba сказал мне, что мне не нужен xa и двухфазная фиксация, потому что схемы находятся на одном сервере.Так что я использовал не-XA подход с Atomikos.следующий код в одной схеме работает нормально (фиксация и откат, как и ожидалось):
utx.begin();
conn = //get connection
if (sAzione.equals("1"))
sql = "UPDATE parametri set valore =to_char(sysdate,'dd/mm/yyyy HH24:MI:ss') where id_parametri= 9 ";
//execute query
sql = "SELECT SEQ_LOTTO.nextval id FROM dual";
//other operations
sql = "INSERT INTO LOTTO (id_lotto, numero_lotto, id_area, id_stato_lavorazione, id_autore, id_tipo)";
sql = sql + " VALUES (" + id + ", " + numero + ", " + request.getParameter("idArea") + ",1,"+ session.getAttribute("id_anagrafica")+ "," + request.getParameter("idTipo") + ")";
//execute import and release connection
utx.commit();
в другом месте вызывается следующая функция oracle, которая пытается изменить обе схемы и возвращает код 1.Я не знаю pl-slq, но мне кажется, что возвращаемое значение будет означать, что при первом удалении произошла исключительная ситуация, но второе удаление выполняется и фиксируется.Кто-то может объяснить мне значение этой функции?ниже приведена функция и код, который ее вызывает
create or replace FUNCTION FN_ELIMINA_RACC (idracc IN NUMBER, idlotto IN NUMBER)
RETURN NUMBER
IS
retvalue NUMBER (1);
BEGIN
retvalue := 1;
DELETE FROM npa_collaudo.documento_raccomandata
WHERE id_raccomandata = idracc;
retvalue := 2;
DELETE FROM raccomandata_out
WHERE id_racc_out = idracc;
retvalue := 3;
IF idlotto != 0
THEN
UPDATE lotto
SET numero_racc = numero_racc - 1
WHERE id_lotto = idlotto;
END IF;
retvalue := 0;
COMMIT;
RETURN retvalue;
EXCEPTION
WHEN OTHERS
THEN
RETURN retvalue;
END;
//the calling code
utx.begin();
//get connection
sql = "FN_ELIMINA_RACC(" + idRacc + ", " + idLotto + ");";
ret = connessioneDB.eseguiSP(sql);
if (!(ret == 0)){
throw new Exception("exception");
utx.commit();
//since it returns 1 an exception is raised and rollback gets called
Заранее благодарим вас за любую помощь
РЕДАКТИРОВАТЬ: дальнейшее изучение этого (ужасного) кода, и благодаря вашим ответам яЯ нашел это в печально известном "eseguiSP":
//strSQL is "FN_ELIMINA_RACC(..."
DBOracle dbType = new DBOracle();
String SQL = "";
int retValue = 0;
SQL = " DECLARE ";
SQL = SQL + " ret NUMBER; ";
SQL = SQL + " BEGIN ";
SQL = SQL + " ret := " + strSQL;
SQL = SQL + " END; ";
try {
stmt = conn.prepareCall(SQL);
retValue = stmt.executeUpdate(SQL);
} catch (SQLException e) {
//retValue = false;
}
return retValue;
И я изменил его на:
c = ds.getConnection();
java.sql.CallableStatement cstmt = c.prepareCall("{?=call FN_ELIMINA_RACC(?,?)}");
cstmt.registerOutParameter(1,java.sql.Types.INTEGER);
cstmt.setInt(2, idRacc);
cstmt.setInt(3, idLotto);
cstmt.execute();
ret = cstmt.getInt(1);
Теперь он работает нормально (или, по крайней мере, возвращает 0). Почемустарый кусок кода всегда возвращал 1, даже если он удалял записи из raccomandata_out?