TransactionServerUtils.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.core.transazioni.utils;

  21. import java.security.SecureRandom;
  22. import java.sql.Connection;
  23. import java.sql.PreparedStatement;
  24. import java.sql.ResultSet;
  25. import java.sql.Timestamp;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. import java.util.Map;

  29. import org.openspcoop2.core.commons.CoreException;
  30. import org.openspcoop2.core.commons.DBUtils;
  31. import org.openspcoop2.core.commons.IDAOFactory;
  32. import org.openspcoop2.core.constants.CostantiDB;
  33. import org.openspcoop2.core.transazioni.IdTransazioneApplicativoServer;
  34. import org.openspcoop2.core.transazioni.Transazione;
  35. import org.openspcoop2.core.transazioni.TransazioneApplicativoServer;
  36. import org.openspcoop2.core.transazioni.dao.ITransazioneApplicativoServerService;
  37. import org.openspcoop2.core.transazioni.dao.jdbc.JDBCTransazioneApplicativoServerService;
  38. import org.openspcoop2.core.transazioni.dao.jdbc.JDBCTransazioneService;
  39. import org.openspcoop2.core.transazioni.dao.jdbc.converter.TransazioneFieldConverter;
  40. import org.openspcoop2.generic_project.beans.UpdateField;
  41. import org.openspcoop2.generic_project.exception.MultipleResultException;
  42. import org.openspcoop2.generic_project.exception.NotFoundException;
  43. import org.openspcoop2.generic_project.exception.NotImplementedException;
  44. import org.openspcoop2.generic_project.exception.ServiceException;
  45. import org.openspcoop2.generic_project.expression.IPaginatedExpression;
  46. import org.openspcoop2.generic_project.utils.ServiceManagerProperties;
  47. import org.openspcoop2.utils.Utilities;
  48. import org.openspcoop2.utils.date.DateManager;
  49. import org.openspcoop2.utils.date.DateUtils;
  50. import org.openspcoop2.utils.jdbc.JDBCUtilities;
  51. import org.openspcoop2.utils.sql.Case;
  52. import org.openspcoop2.utils.sql.CastColumnType;
  53. import org.openspcoop2.utils.sql.ISQLQueryObject;
  54. import org.openspcoop2.utils.sql.SQLObjectFactory;
  55. import org.slf4j.Logger;

  56. /**    
  57.  * TransactionServerUtils
  58.  *
  59.  * @author Poli Andrea (poli@link.it)
  60.  * @author $Author$
  61.  * @version $Rev$, $Date$
  62.  */
  63. public class TransactionServerUtils {

  64.     private TransactionServerUtils() {}
  65.    
  66.     // *** SAVE ***
  67.    
  68.     public static boolean recover(ITransazioneApplicativoServerService transazioneService, TransazioneApplicativoServer serverInfoParam) throws CoreException, ServiceException, NotImplementedException, NotFoundException, MultipleResultException  {
  69.        
  70.         String idTransazione = serverInfoParam.getIdTransazione();
  71.         if(idTransazione==null) {
  72.             throw new CoreException("IdTransazione non esistente nel contesto");
  73.         }
  74.        
  75.         String servizioApplicativoErogatore = serverInfoParam.getServizioApplicativoErogatore();
  76.         if(servizioApplicativoErogatore==null) {
  77.             throw new CoreException("Id servizioApplicativoErogatore non esistente nel contesto");
  78.         }
  79.        
  80.         boolean firstEntry = serverInfoParam.getDataUscitaRichiesta()==null && serverInfoParam.getDataPrelievoIm()==null && serverInfoParam.getDataEliminazioneIm()==null;
  81.        
  82.         if(firstEntry) {
  83.             return save(transazioneService, serverInfoParam, false, false, true, false, null);      
  84.         }
  85.         else {
  86.             IdTransazioneApplicativoServer idTransazioneApplicativoServer = new IdTransazioneApplicativoServer();
  87.             idTransazioneApplicativoServer.setIdTransazione(idTransazione);
  88.             idTransazioneApplicativoServer.setServizioApplicativoErogatore(servizioApplicativoErogatore);
  89.             if(transazioneService.exists(idTransazioneApplicativoServer)) {
  90.                
  91.                 TransazioneApplicativoServer transazioneApplicativoServer = transazioneService.get(idTransazioneApplicativoServer);
  92.                 if(!transazioneApplicativoServer.isConsegnaTerminata() && transazioneApplicativoServer.getDataEliminazioneIm()==null && transazioneApplicativoServer.getDataMessaggioScaduto()==null) {
  93.                     boolean useSelectForUpdate = true;
  94.                     /*
  95.                      * Grazie alla select for update riesco a mettere il lock solamente sulla riga interessata
  96.                      */
  97.                     return save(transazioneService, serverInfoParam, true, false, true, useSelectForUpdate, null);
  98.                 }
  99.                 // else ho già registrato l'ultima informazione, è inutile fare update delle informazioni parziali.
  100.                 else {
  101.                     return false;
  102.                 }
  103.             }
  104.             else {
  105.                 throw new CoreException("In attesa della registrazione dell'informazione capostipite");
  106.             }
  107.         }
  108.        
  109.     }
  110.    
  111.     public static boolean save(ITransazioneApplicativoServerService transazioneService, TransazioneApplicativoServer serverInfoParam, boolean update, boolean throwNotFoundIfNotExists, boolean recover,
  112.             boolean useSelectForUpdate, List<String> timeDetails) throws CoreException, ServiceException, NotImplementedException, NotFoundException, MultipleResultException {
  113.        
  114.         if(recover) {
  115.             // nop
  116.         }
  117.        
  118.         String idTransazione = serverInfoParam.getIdTransazione();
  119.         if(idTransazione==null) {
  120.             throw new CoreException("IdTransazione non esistente nel contesto");
  121.         }
  122.        
  123.         String servizioApplicativoErogatore = serverInfoParam.getServizioApplicativoErogatore();
  124.         if(servizioApplicativoErogatore==null) {
  125.             throw new CoreException("Id servizioApplicativoErogatore non esistente nel contesto");
  126.         }
  127.        
  128.         /**System.out.println("SAVE id["+idTransazione+"] ["+servizioApplicativoErogatore+"] update:"+update+" ....");*/
  129.        
  130.         String protocol = serverInfoParam.getProtocollo();
  131.         if(protocol==null) {
  132.             throw new CoreException("Protocollo non esistente nel contesto");
  133.         }
  134.        
  135.         IdTransazioneApplicativoServer idTransazioneApplicativoServer = new IdTransazioneApplicativoServer();
  136.         idTransazioneApplicativoServer.setIdTransazione(idTransazione);
  137.         idTransazioneApplicativoServer.setServizioApplicativoErogatore(servizioApplicativoErogatore);
  138.        
  139.        
  140.        
  141.         if(update) {
  142.            
  143.             long timeStart = -1;
  144.             if(timeDetails!=null) {
  145.                 timeStart = DateManager.getTimeMillis();
  146.             }
  147.            
  148.             // prima era inefficiente: faceva 2 query
  149.             // adesso e' stata trasformata in efficiente e fa una unica query con limit 1
  150.             TransazioneApplicativoServer transazioneApplicativoServerReadFromDB = null;
  151.             IdTransazioneApplicativoServer idTransazioneApplicativoServerReadFromDB = null;
  152.             if(useSelectForUpdate) {
  153.                 JDBCTransazioneApplicativoServerService transazioneServiceSearch = (JDBCTransazioneApplicativoServerService) transazioneService;
  154.                 try {
  155.                     transazioneServiceSearch.enableSelectForUpdate();
  156.                     transazioneApplicativoServerReadFromDB = transazioneService.get(idTransazioneApplicativoServer);
  157.                 }finally {
  158.                     transazioneServiceSearch.disableSelectForUpdate();
  159.                 }
  160.                 // con la select for update devo poi usare lo stesso comando di WHERE poichè ho messo un lock sulla riga
  161.                 // uso quindi idTransazioneApplicativoServer che non possiede l'id long settato
  162.                 idTransazioneApplicativoServerReadFromDB = idTransazioneApplicativoServer;
  163.             }
  164.             else{
  165.                 transazioneApplicativoServerReadFromDB = transazioneService.get(idTransazioneApplicativoServer);
  166.                 idTransazioneApplicativoServerReadFromDB = new IdTransazioneApplicativoServer();
  167.                 idTransazioneApplicativoServerReadFromDB.setId(transazioneApplicativoServerReadFromDB.getId());
  168.             }
  169.            
  170.             if(timeDetails!=null) {
  171.                 long timeEnd =  DateManager.getTimeMillis();
  172.                 long timeProcess = timeEnd-timeStart;
  173.                 timeDetails.add("readFromDB:"+timeProcess);
  174.                
  175.                 timeStart = DateManager.getTimeMillis();
  176.             }
  177.            
  178.             if(throwNotFoundIfNotExists) {
  179.                 // non più usato
  180.             }
  181.             /**
  182.              * Leggermente inefficiente per via del limit 2 con cui viene implementata la find
  183.             org.openspcoop2.generic_project.expression.IExpression expression = transazioneService.newExpression();
  184.             expression.equals(TransazioneApplicativoServer.model().ID_TRANSAZIONE, idTransazione);
  185.             expression.and();
  186.             expression.equals(TransazioneApplicativoServer.model().SERVIZIO_APPLICATIVO_EROGATORE, servizioApplicativoErogatore);
  187.             TransazioneApplicativoServer transazioneApplicativoServerReadFromDB = null;
  188.             try {
  189.                 transazioneApplicativoServerReadFromDB = transazioneService.find(expression);
  190.             }catch(NotFoundException notfound) {
  191.                 if(throwNotFoundIfNotExists) {
  192.                     throw notfound;
  193.                 }
  194.                 else {
  195.                     return false;
  196.                 }
  197.             }*/
  198.            
  199.             // aggiorno data registrazione per controllo effettuato durante l'aggiornamento della transazione (metodo sotto: aggiornaInformazioneConsegnaTerminata)
  200.             serverInfoParam.setDataRegistrazione(transazioneApplicativoServerReadFromDB.getDataRegistrazione());
  201.            
  202.                        
  203.             if(serverInfoParam.getDataMessaggioScaduto()!=null) {
  204.                
  205.                 if( transazioneApplicativoServerReadFromDB.getDataMessaggioScaduto()!=null ) {
  206.                     return false; // l'informazione salvata sul database indica già un messaggio scaduto.
  207.                 }
  208.                
  209.                 // date
  210.                 transazioneApplicativoServerReadFromDB.setDataMessaggioScaduto(serverInfoParam.getDataMessaggioScaduto());
  211.                
  212.             }
  213.             else if(serverInfoParam.getDataEliminazioneIm()!=null) {
  214.                
  215.                 if( transazioneApplicativoServerReadFromDB.getDataEliminazioneIm()!=null ) {
  216.                     return false; // l'informazione salvata sul database indica già un messaggio eliminato via I.M..
  217.                 }
  218.                
  219.                 // date
  220.                 transazioneApplicativoServerReadFromDB.setDataEliminazioneIm(serverInfoParam.getDataEliminazioneIm());
  221.                
  222.                 // cluster id
  223.                 transazioneApplicativoServerReadFromDB.setClusterIdEliminazioneIm(serverInfoParam.getClusterIdEliminazioneIm());
  224.                
  225.                 // segno come completata
  226.                 transazioneApplicativoServerReadFromDB.setConsegnaTerminata(true);
  227.                
  228.             }
  229.             else if(serverInfoParam.getDataPrelievoIm()!=null) {
  230.                
  231.                 if( transazioneApplicativoServerReadFromDB.getDataEliminazioneIm()!=null ) {
  232.                     return false; // l'informazione salvata sul database indica già un messaggio eliminato via I.M..
  233.                 }
  234.                
  235.                 // date
  236.                 transazioneApplicativoServerReadFromDB.setDataPrelievoIm(serverInfoParam.getDataPrelievoIm());
  237.                
  238.                 // data primo tentativo
  239.                 if(transazioneApplicativoServerReadFromDB.getDataPrimoPrelievoIm()==null &&
  240.                     serverInfoParam.getDataPrelievoIm()!=null) {
  241.                     transazioneApplicativoServerReadFromDB.setDataPrimoPrelievoIm(serverInfoParam.getDataPrelievoIm()); // primo tentativo di prelievo
  242.                 }
  243.                
  244.                 // numero tentativi
  245.                 transazioneApplicativoServerReadFromDB.setNumeroPrelieviIm(transazioneApplicativoServerReadFromDB.getNumeroPrelieviIm()+1);
  246.    
  247.                 // cluster id
  248.                 transazioneApplicativoServerReadFromDB.setClusterIdPrelievoIm(serverInfoParam.getClusterIdPrelievoIm());
  249.                
  250.             }
  251.             else {
  252.            
  253.                 if( transazioneApplicativoServerReadFromDB.isConsegnaTerminata() ) {
  254.                     return false; // l'informazione salvata sul database indica già un messaggio completato.
  255.                 }
  256.                
  257.                 // ** successivi invii **
  258.                
  259.                 // id transazione, servizio applicativo erogatore e data registrazione non sono da aggiornare
  260.                                            
  261.                 // esito
  262.                 transazioneApplicativoServerReadFromDB.setConsegnaTerminata(serverInfoParam.isConsegnaTerminata());
  263.                 transazioneApplicativoServerReadFromDB.setDettaglioEsito(serverInfoParam.getDettaglioEsito());
  264.                
  265.                 // date
  266.                 transazioneApplicativoServerReadFromDB.setDataAccettazioneRichiesta(serverInfoParam.getDataAccettazioneRichiesta());
  267.                 transazioneApplicativoServerReadFromDB.setDataUscitaRichiesta(serverInfoParam.getDataUscitaRichiesta());
  268.                 transazioneApplicativoServerReadFromDB.setDataUscitaRichiestaStream(serverInfoParam.getDataUscitaRichiestaStream());
  269.                 transazioneApplicativoServerReadFromDB.setDataAccettazioneRisposta(serverInfoParam.getDataAccettazioneRisposta());
  270.                 transazioneApplicativoServerReadFromDB.setDataIngressoRisposta(serverInfoParam.getDataIngressoRisposta());
  271.                 transazioneApplicativoServerReadFromDB.setDataIngressoRispostaStream(serverInfoParam.getDataIngressoRispostaStream());
  272.                
  273.                 // dimensioni
  274.                 transazioneApplicativoServerReadFromDB.setRichiestaUscitaBytes(serverInfoParam.getRichiestaUscitaBytes());
  275.                 transazioneApplicativoServerReadFromDB.setRispostaIngressoBytes(serverInfoParam.getRispostaIngressoBytes());
  276.            
  277.                 // location e codice risposta
  278.                 transazioneApplicativoServerReadFromDB.setLocationConnettore(serverInfoParam.getLocationConnettore());
  279.                 transazioneApplicativoServerReadFromDB.setCodiceRisposta(serverInfoParam.getCodiceRisposta());
  280.                
  281.                 // fault
  282.                 transazioneApplicativoServerReadFromDB.setFault(serverInfoParam.getFault());
  283.                 transazioneApplicativoServerReadFromDB.setFormatoFault(serverInfoParam.getFormatoFault());
  284.                
  285.                 // data primo tentativo
  286.                 if(transazioneApplicativoServerReadFromDB.getDataPrimoTentativo()==null &&
  287.                     serverInfoParam.getDataUscitaRichiesta()!=null) {
  288.                     transazioneApplicativoServerReadFromDB.setDataPrimoTentativo(serverInfoParam.getDataUscitaRichiesta()); // primo tentativo di consegna
  289.                 }
  290.                
  291.                 // numero tentativi
  292.                 transazioneApplicativoServerReadFromDB.setNumeroTentativi(transazioneApplicativoServerReadFromDB.getNumeroTentativi()+1);  
  293.    
  294.                 // cluster id
  295.                 transazioneApplicativoServerReadFromDB.setClusterIdConsegna(serverInfoParam.getClusterIdConsegna());
  296.                
  297.                
  298.                 // aggiorno errore e fault se ho uno stato non ok
  299.                
  300.                 if(!serverInfoParam.isConsegnaTerminata()) {
  301.                    
  302.                     if(serverInfoParam.getDataUscitaRichiesta()!=null) {
  303.                         transazioneApplicativoServerReadFromDB.setDataUltimoErrore(serverInfoParam.getDataUscitaRichiesta());
  304.                     }
  305.                     else {
  306.                         transazioneApplicativoServerReadFromDB.setDataUltimoErrore(serverInfoParam.getDataAccettazioneRichiesta());
  307.                     }
  308.                    
  309.                     transazioneApplicativoServerReadFromDB.setDettaglioEsitoUltimoErrore(serverInfoParam.getDettaglioEsito());
  310.                    
  311.                     transazioneApplicativoServerReadFromDB.setCodiceRispostaUltimoErrore(serverInfoParam.getCodiceRisposta());
  312.                    
  313.                     transazioneApplicativoServerReadFromDB.setUltimoErrore(serverInfoParam.getUltimoErrore());
  314.                    
  315.                     transazioneApplicativoServerReadFromDB.setLocationUltimoErrore(serverInfoParam.getLocationConnettore());
  316.                    
  317.                     transazioneApplicativoServerReadFromDB.setClusterIdUltimoErrore(serverInfoParam.getClusterIdConsegna());
  318.                                    
  319.                     transazioneApplicativoServerReadFromDB.setFaultUltimoErrore(serverInfoParam.getFault());
  320.                     transazioneApplicativoServerReadFromDB.setFormatoFaultUltimoErrore(serverInfoParam.getFormatoFault());
  321.                 }
  322.                
  323.             }
  324.            
  325.             if(timeDetails!=null) {
  326.                 long timeEnd =  DateManager.getTimeMillis();
  327.                 long timeProcess = timeEnd-timeStart;
  328.                 timeDetails.add("prepareUpdate:"+timeProcess);
  329.                
  330.                 timeStart = DateManager.getTimeMillis();
  331.             }
  332.            
  333.             transazioneService.update(idTransazioneApplicativoServerReadFromDB, transazioneApplicativoServerReadFromDB);
  334.            
  335.             if(timeDetails!=null) {
  336.                 long timeEnd =  DateManager.getTimeMillis();
  337.                 long timeProcess = timeEnd-timeStart;
  338.                 timeDetails.add("update:"+timeProcess);
  339.             }
  340.            
  341.             return true;
  342.         }
  343.         else {
  344.            
  345.             long timeStart = -1;
  346.             if(timeDetails!=null) {
  347.                 timeStart = DateManager.getTimeMillis();
  348.             }
  349.            
  350.             // ** primo invio **
  351.            
  352.             TransazioneApplicativoServer transazioneApplicativoServer = serverInfoParam;
  353.            
  354.             // protocollo
  355.             transazioneApplicativoServer.setProtocollo(protocol);
  356.            
  357.             // data registrazione
  358.             if(transazioneApplicativoServer.getDataRegistrazione()==null) {
  359.                 transazioneApplicativoServer.setDataRegistrazione(DateManager.getDate());
  360.             }
  361.            
  362.             // data primo tentativo
  363.             if(transazioneApplicativoServer.getDataUscitaRichiesta()!=null) {
  364.                 transazioneApplicativoServer.setDataPrimoTentativo(transazioneApplicativoServer.getDataUscitaRichiesta()); // primo tentativo di consegna
  365.             }
  366.             if(transazioneApplicativoServer.getDataPrelievoIm()!=null) {
  367.                 transazioneApplicativoServer.setDataPrimoPrelievoIm(transazioneApplicativoServer.getDataPrelievoIm());
  368.             }
  369.            
  370.             // numero tentativi
  371.             transazioneApplicativoServer.setNumeroTentativi(0);
  372.             transazioneApplicativoServer.setNumeroPrelieviIm(0);
  373.            
  374.             // cluster id
  375.             transazioneApplicativoServer.setClusterIdPresaInCarico(serverInfoParam.getClusterIdPresaInCarico());
  376.            
  377.             if(timeDetails!=null) {
  378.                 long timeEnd =  DateManager.getTimeMillis();
  379.                 long timeProcess = timeEnd-timeStart;
  380.                 timeDetails.add("prepareInsert:"+timeProcess);
  381.                
  382.                 timeStart = DateManager.getTimeMillis();
  383.             }
  384.            
  385.             // CREO
  386.             transazioneService.create(transazioneApplicativoServer);

  387.             if(timeDetails!=null) {
  388.                 long timeEnd =  DateManager.getTimeMillis();
  389.                 long timeProcess = timeEnd-timeStart;
  390.                 timeDetails.add("insert:"+timeProcess);
  391.                
  392.                 timeStart = DateManager.getTimeMillis();
  393.             }
  394.            
  395.             return true;
  396.         }

  397.     }
  398.    
  399.     public static boolean safeAggiornaInformazioneConsegnaTerminata(TransazioneApplicativoServer transazioneApplicativoServer, Connection con,
  400.             String tipoDatabase, Logger logCore,
  401.             IDAOFactory daoFactory, Logger logFactory, ServiceManagerProperties smpFactory,
  402.             boolean debug,
  403.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  404.             int esitoIntegrationManagerSingolo, boolean possibileTerminazioneSingleIntegrationManagerMessage, boolean consegnaInErrore,
  405.             long gestioneSerializableDBAttesaAttiva, int gestioneSerializableDBCheckInterval,
  406.             List<String> timeDetails) {
  407.        
  408.         // aggiorno esito transazione
  409.         try{
  410.             return TransactionServerUtils.aggiornaInformazioneConsegnaTerminata(transazioneApplicativoServer, con,
  411.                     tipoDatabase, logCore,
  412.                     daoFactory, logFactory, smpFactory,
  413.                     debug,
  414.                     esitoConsegnaMultipla, esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  415.                     esitoIntegrationManagerSingolo, possibileTerminazioneSingleIntegrationManagerMessage, consegnaInErrore,
  416.                     gestioneSerializableDBAttesaAttiva, gestioneSerializableDBCheckInterval,
  417.                     timeDetails);
  418.         }catch(Throwable e){
  419.             /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] ERRORE AGGIORNAMENTO: "+e.getMessage());
  420.             e.printStackTrace(System.out);*/
  421.             String msg = "Errore durante l'aggiornamento delle transazione relativamente all'informazione del server: " + e.getLocalizedMessage();
  422.             logCore.error("[id:"+transazioneApplicativoServer.getIdTransazione()+"][sa:"+transazioneApplicativoServer.getServizioApplicativoErogatore()+"]["+transazioneApplicativoServer.getConnettoreNome()+"] "+msg,e);
  423.             return false;
  424.         }
  425.     }
  426.    
  427.     private static boolean aggiornaInformazioneConsegnaTerminata(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  428.             String tipoDatabase, Logger logCore,
  429.             IDAOFactory daoFactory, Logger logFactory, ServiceManagerProperties smpFactory,
  430.             boolean debug,
  431.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  432.             int esitoIntegrationManagerSingolo, boolean possibileTerminazioneSingleIntegrationManagerMessage, boolean consegnaInErrore,
  433.             long gestioneSerializableDBAttesaAttiva, int gestioneSerializableDBCheckInterval,
  434.             List<String> timeDetails) throws CoreException {
  435.        
  436.         boolean consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda = false;
  437.        
  438.         if(possibileTerminazioneSingleIntegrationManagerMessage || consegnaInErrore) {
  439.             // possibileTerminazioneSingleIntegrationManagerMessage
  440.             // Devo comprendere se l'eliminazione del messaggio, effettuata via I.M o tramite scadenza, riguarda la configurazione su connettori multipli o configurazione standard con unico connettore.
  441.             // Se e' su configurazione standard con unico connettore non devo aggiornare le informazioni sulla consegna terminata
  442.            
  443.             // possibilePrimaConsegnaNonAndataABuonFine
  444.             // Devo comprendere se si tratta di una prima consegna, non completata. Serve per aggiornare lo stato della transazione da "In coda" a "In corso"
  445.            
  446.             int i = 0;
  447.             if(transazioneApplicativoServer.getDataRegistrazione()==null) {
  448.                 i=2;
  449.             }
  450. /**         else {
  451.                 System.out.println("DATA REGISTRAZIONE '"+org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(transazioneApplicativoServer.getDataRegistrazione())+"'");
  452.             }*/
  453.             int esitoTransazione = -1;
  454.             for (; i < 3; i++) {
  455.                
  456.                 long timeStart = -1;
  457.                 if(timeDetails!=null) {
  458.                     timeStart = DateManager.getTimeMillis();
  459.                 }
  460.                
  461.                 // primo test: finestra di 5 minuti
  462.                 // secondo test: finestra di 1 ora
  463.                 // terzo test: senza finestra temporale
  464.                
  465.                 /**System.out.println("INTERVALLO '"+i+"'");*/
  466.                
  467.                 Timestamp leftValue = null;
  468.                 Timestamp rightValue = null;
  469.                 if(i==0) {
  470.                     leftValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() - (1000*60*5));
  471.                     rightValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() + (1000*60*5));
  472.                 }
  473.                 else if(i==1) {
  474.                     leftValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() - (1000*60*60));
  475.                     rightValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() + (1000*60*60));
  476.                 }
  477.            
  478.                 esitoTransazione = getEsitoTransazione(transazioneApplicativoServer, connectionDB,
  479.                         tipoDatabase, logCore,
  480.                         leftValue, rightValue);
  481.                
  482.                 if(timeDetails!=null) {
  483.                     long timeEnd =  DateManager.getTimeMillis();
  484.                     long timeProcess = timeEnd-timeStart;
  485.                     timeDetails.add("getEsitoIM-"+i+":"+timeProcess);
  486.                 }
  487.                
  488.                 if(esitoTransazione>=0) {
  489.                     // transazione trovata
  490.                     if(possibileTerminazioneSingleIntegrationManagerMessage &&
  491.                         esitoIntegrationManagerSingolo == esitoTransazione) {
  492.                         /**System.out.println("TROVATA IM; termino aggiornamento");*/
  493.                         return true; // non devo gestire l'update previsto nei connettori multipli gestito dopo
  494.                     }
  495.                     if(consegnaInErrore) {
  496.                         if(esitoConsegnaMultipla == esitoTransazione) {
  497.                             consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda = true;
  498.                         }
  499.                         else {
  500.                             /**System.out.println("TROVATA TRANSAZIONE CON ESITO "+esitoTransazione+" non "in coda"; termino aggiornamento");*/
  501.                             return true; // non devo gestire l'update previsto nei connettori multipli gestito dopo
  502.                         }
  503.                     }
  504.                     /**else {
  505.                         System.out.println("ESCO e procedo con update normale ["+i+"]");
  506.                     }*/
  507.                     break;
  508.                 }
  509.                 /**else {
  510.                     System.out.println("NON TROVATA TRANSAZIONE a QUESTO GIRO ["+i+"]");
  511.                 }*/
  512.                
  513.             }
  514.             if(esitoTransazione<0) {
  515.                 // registro ultimo errore avvenuto durante il ciclo in entrambi i log
  516.                 String msgError = "[id:"+transazioneApplicativoServer.getIdTransazione()+"][sa:"+transazioneApplicativoServer.getServizioApplicativoErogatore()+"]["+transazioneApplicativoServer.getConnettoreNome()+"] 'getEsitoTransazione' non riuscta. Tutti gli intervalli non hanno consentito di inviduare la transazione";
  517.                 logFactory.error(msgError);
  518.                 logCore.error(msgError);
  519.             }
  520.            
  521.         }
  522.        
  523.         return aggiornaInformazioneConsegnaTerminataEngine(transazioneApplicativoServer, connectionDB,
  524.                 tipoDatabase, logCore,
  525.                 daoFactory, logFactory, smpFactory,
  526.                 debug,
  527.                 esitoConsegnaMultipla, esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  528.                 consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  529.                 gestioneSerializableDBAttesaAttiva, gestioneSerializableDBCheckInterval,
  530.                 timeDetails);
  531.     }
  532.     private static boolean aggiornaInformazioneConsegnaTerminataEngine(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  533.             String tipoDatabase, Logger logCore,
  534.             IDAOFactory daoFactory, Logger logFactory, ServiceManagerProperties smpFactory,
  535.             boolean debug,
  536.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  537.             boolean consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  538.             long gestioneSerializableDBAttesaAttiva, int gestioneSerializableDBCheckInterval,
  539.             List<String> timeDetails) throws CoreException {
  540.        
  541.         boolean useSerializableMode = false;
  542.         if(useSerializableMode) {
  543.             serializableModeAggiornaInformazioneConsegnaTerminataEngine(transazioneApplicativoServer, connectionDB,
  544.                     tipoDatabase, logCore,
  545.                     daoFactory, logFactory, smpFactory,
  546.                     debug,
  547.                     esitoConsegnaMultipla, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  548.                     consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  549.                     gestioneSerializableDBAttesaAttiva, gestioneSerializableDBCheckInterval);
  550.             return true; // non gestisco l'informazione ritornata essendo il metodo deprecato
  551.         }
  552.         else {
  553.            
  554.             boolean transazioneGiaModificata = false;
  555.            
  556.             int i = 0;
  557.             if(transazioneApplicativoServer.getDataRegistrazione()==null) {
  558.                 i=2;
  559.             }
  560. /**         else {
  561.                 System.out.println("DATA REGISTRAZIONE '"+org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(transazioneApplicativoServer.getDataRegistrazione())+"'");
  562.             }*/
  563.             int row = -1;
  564.             for (; i < 3; i++) {
  565.                
  566.                 long timeStart = -1;
  567.                 if(timeDetails!=null) {
  568.                     timeStart = DateManager.getTimeMillis();
  569.                 }
  570.                
  571.                 // primo test: finestra di 5 minuti
  572.                 // secondo test: finestra di 1 ora
  573.                 // terzo test: senza finestra temporale
  574.                
  575.                 /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] INTERVALLO '"+i+"'");*/
  576.                
  577.                 Timestamp leftValue = null;
  578.                 Timestamp rightValue = null;
  579.                 if(i==0) {
  580.                     leftValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() - (1000*60*5));
  581.                     rightValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() + (1000*60*5));
  582.                 }
  583.                 else if(i==1) {
  584.                     leftValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() - (1000*60*60));
  585.                     rightValue = new Timestamp(transazioneApplicativoServer.getDataRegistrazione().getTime() + (1000*60*60));
  586.                 }
  587.            
  588.                 boolean useSERIALIZABLE = true;
  589.                 StringBuilder sbConflict = new StringBuilder();
  590.                 row = aggiornaInformazioneConsegnaTerminataEngine(transazioneApplicativoServer, connectionDB,
  591.                         tipoDatabase, logCore,
  592.                         logFactory,
  593.                         esitoConsegnaMultipla, esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  594.                         consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  595.                         leftValue, rightValue,
  596.                         useSERIALIZABLE,
  597.                         gestioneSerializableDBAttesaAttiva, gestioneSerializableDBCheckInterval,
  598.                         sbConflict);
  599.                
  600.                 if(timeDetails!=null) {
  601.                     long timeEnd =  DateManager.getTimeMillis();
  602.                     long timeProcess = timeEnd-timeStart;
  603.                     String c = "";
  604.                     if(useSERIALIZABLE &&
  605.                         sbConflict.length()>0) {
  606.                         c="/c"+sbConflict.toString();
  607.                     }
  608.                     timeDetails.add("updateInfo-"+i+":"+timeProcess+c);
  609.                 }
  610.                
  611.                 if(row>0) {
  612.                     break;
  613.                 }
  614.                 else if(consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda) {
  615.                     /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] existsTransazioneIniziataGestioneConsegnaAsincrona ...");*/
  616.                     // in questo caso si sta cercando di aggiornare l'esito:
  617.                     //   UPDATE transazioni SET esito = 48 WHERE ( .... ) ( esito=38 )
  618.                     // ma se una transazione in parallelo l'ha già modificato si ottiene un row=0 che faceva ritornare false questo metodo, faceva scaturire la registrazione su file e poi l'aggiornamenti di avvenuta consegna che non era corretta.
  619.                     transazioneGiaModificata = existsTransazioneIniziataGestioneConsegnaAsincrona(transazioneApplicativoServer, connectionDB,
  620.                             tipoDatabase, logCore,
  621.                             esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata,
  622.                             leftValue, rightValue);
  623.                     if(transazioneGiaModificata) {
  624.                         /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] existsTransazioneIniziataGestioneConsegnaAsincrona FIX");*/
  625.                         break;
  626.                     }
  627.                     /**else {
  628.                         System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] existsTransazioneIniziataGestioneConsegnaAsincrona NO");
  629.                     }*/
  630.                 }
  631.                
  632.             }
  633.             if(row<=0 && !transazioneGiaModificata) {
  634.                 // registro ultimo errore avvenuto durante il ciclo in entrambi i log
  635.                 String msgError = "[id:"+transazioneApplicativoServer.getIdTransazione()+"][sa:"+transazioneApplicativoServer.getServizioApplicativoErogatore()+"]["+transazioneApplicativoServer.getConnettoreNome()+"] 'aggiornaInformazioneConsegnaTerminata' non riuscta. Tutti gli intervalli di update non hanno comportato un aggiornamento della transazione";
  636.                 logFactory.error(msgError);
  637.                 logCore.error(msgError);
  638.                 /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] INTERVALLO '"+i+"' FINITO OK FALSE ========================================");*/
  639.                 return false;
  640.             }
  641.             else {
  642.                 /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] INTERVALLO '"+i+"' FINITO TRUE");*/
  643.                 return true;
  644.             }
  645.         }
  646.        
  647.     }
  648.    
  649.     private static java.util.Random rndInstance = null;
  650.     private static synchronized void initRandom() {
  651.         if(rndInstance==null) {
  652.             rndInstance = new SecureRandom();
  653.         }
  654.     }
  655.     protected static java.util.Random getRandom() {
  656.         if(rndInstance==null) {
  657.             initRandom();
  658.         }
  659.         return rndInstance;
  660.     }
  661.    
  662.     private static int aggiornaInformazioneConsegnaTerminataEngine(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  663.             String tipoDatabase, Logger logCore,
  664.             Logger logFactory,
  665.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  666.             boolean consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  667.             Timestamp leftValue, Timestamp rightValue,
  668.             boolean serializable,
  669.             long gestioneSerializableDBAttesaAttiva, int gestioneSerializableDBCheckInterval,
  670.             StringBuilder sbConflict) throws CoreException {
  671.        
  672.         /**System.out.println("SERIALIZABLE ("+transazioneApplicativoServer.getConnettoreNome()+"): "+serializable);*/
  673.         if(serializable) {
  674.            
  675.             /*
  676.               Viene realizzato con livello di isolamento SERIALIZABLE, per essere sicuri
  677.               che esecuzioni parallele non leggano dati inconsistenti.
  678.               Con il livello SERIALIZABLE, se ritorna una eccezione, deve essere riprovato
  679.               La sincronizzazione e' necessaria per via del possibile accesso simultaneo del servizio Gop
  680.               e del servizio che si occupa di eliminare destinatari di messaggi
  681.              */
  682.             // setAutoCommit e livello Isolamento
  683.             int oldTransactionIsolation = -1;
  684.             try{
  685.                 oldTransactionIsolation = connectionDB.getTransactionIsolation();
  686.                 /** già effettuato fuori dal metodo connectionDB.setAutoCommit(false);*/
  687.                 JDBCUtilities.setTransactionIsolationSerializable(tipoDatabase, connectionDB);
  688.             } catch(Exception er) {
  689.                 throw new CoreException("(setIsolation) "+er.getMessage(),er);
  690.             }

  691.             boolean updateEffettuato = false;
  692.            
  693.             long scadenzaWhile = DateManager.getTimeMillis() + gestioneSerializableDBAttesaAttiva;
  694.            
  695.             int row = -1;
  696.             Throwable lastT = null;
  697.             int conflitti = 0;
  698.             while(!updateEffettuato && DateManager.getTimeMillis() < scadenzaWhile){

  699.                 try{
  700.                     row = aggiornaInformazioneConsegnaTerminataEngine(transazioneApplicativoServer, connectionDB,
  701.                             tipoDatabase, logCore,
  702.                             esitoConsegnaMultipla, esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  703.                             consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  704.                             leftValue, rightValue);

  705.                     updateEffettuato = true;
  706.                     /**System.out.println("["+transazioneApplicativoServer.getConnettoreNome()+"] ["+transazioneApplicativoServer.getIdTransazione()+"] OK row:"+row);*/

  707.                 } catch(Throwable e) {
  708.                     lastT = e;
  709.                     /**System.out.println("Serializable error ("+transazioneApplicativoServer.getConnettoreNome()+")  ["+transazioneApplicativoServer.getIdTransazione()+"] (row:"+row+" updateEffettuato:"+updateEffettuato+"):"+e.getMessage());*/
  710.                 }

  711.                 if(!updateEffettuato){
  712.                     // Per aiutare ad evitare conflitti
  713.                     try{
  714.                         Utilities.sleep(getRandom().nextInt(gestioneSerializableDBCheckInterval)); // random da 0ms a checkIntervalms
  715.                     }catch(Exception eRandom){
  716.                         // random
  717.                     }
  718.                     conflitti++;
  719.                 }
  720.             }
  721.             sbConflict.append(conflitti+"/updated:"+updateEffettuato);
  722.             // Ripristino Transazione
  723.             try{
  724.                 connectionDB.setTransactionIsolation(oldTransactionIsolation);
  725.                 /** già effettuato fuori dal metodo connectionDB.setAutoCommit(true);*/
  726.             } catch(Exception er) {
  727.                 throw new CoreException("(ripristinoIsolation) "+er.getMessage(),er);
  728.             }
  729.             if(lastT!=null && !updateEffettuato) {
  730.                 // registro ultimo errore avvenuto durante il ciclo in entrambi i log
  731.                 String date = "";
  732.                 if(leftValue!=null || rightValue!=null) {
  733.                     StringBuilder sb = new StringBuilder(" [");
  734.                     if(leftValue!=null) {
  735.                         sb.append(DateUtils.getSimpleDateFormatMs().format(leftValue));
  736.                         if(rightValue!=null) {
  737.                             sb.append(" - ");
  738.                         }
  739.                     }
  740.                     if(rightValue!=null) {
  741.                         sb.append(DateUtils.getSimpleDateFormatMs().format(rightValue));
  742.                     }
  743.                     sb.append("]");
  744.                     date = sb.toString();
  745.                 }
  746.                 String msgError = "[id:"+transazioneApplicativoServer.getIdTransazione()+"][sa:"+transazioneApplicativoServer.getServizioApplicativoErogatore()+"]["+transazioneApplicativoServer.getConnettoreNome()+"] 'aggiornaInformazioneConsegnaTerminata'"+date+" failed: "+lastT.getMessage();
  747.                 logFactory.error(msgError,lastT);
  748.                 logCore.error(msgError,lastT);
  749.             }
  750.            
  751.             return row;

  752.         }
  753.         else {
  754.            
  755.             return aggiornaInformazioneConsegnaTerminataEngine(transazioneApplicativoServer, connectionDB,
  756.                     tipoDatabase, logCore,
  757.                     esitoConsegnaMultipla, esitoConsegnaMultiplaInCorso, esitoConsegnaMultiplaFallita, esitoConsegnaMultiplaCompletata, ok,
  758.                     consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  759.                     leftValue, rightValue);
  760.            
  761.         }
  762.     }
  763.    
  764.     private static int aggiornaInformazioneConsegnaTerminataEngine(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  765.             String tipoDatabase, Logger logCore,
  766.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  767.             boolean consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  768.             Timestamp leftValue, Timestamp rightValue) throws CoreException {
  769.    
  770.         PreparedStatement pstmt = null;
  771.         try {
  772.        
  773.             TransazioneFieldConverter transazioneFieldConverter = new TransazioneFieldConverter(tipoDatabase);
  774.             String dataIngressoRichiestaColumn = transazioneFieldConverter.toColumn(Transazione.model().DATA_INGRESSO_RICHIESTA, false);
  775.             String idTransazioneColumn = transazioneFieldConverter.toColumn(Transazione.model().ID_TRANSAZIONE, false);
  776.             String esitoColumn = transazioneFieldConverter.toColumn(Transazione.model().ESITO, false);
  777.             String consegneMultipleInCorsoColumn = transazioneFieldConverter.toColumn(Transazione.model().CONSEGNE_MULTIPLE_IN_CORSO, false);
  778.            
  779.             ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(tipoDatabase);
  780.            
  781.             sqlQueryObject.addUpdateTable(CostantiDB.TRANSAZIONI);
  782.            
  783.             if(consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda) {
  784.                 /* UPDATE transazioni
  785.                  *      SET esito=esitoConsegnaMultiplaInCorso  
  786.                  * WHERE (ESITO=esitoConsegnaMultipla)
  787.                  */
  788.                 sqlQueryObject.addUpdateField(esitoColumn,"?");  
  789.             }
  790.             else {
  791.            
  792.                 sqlQueryObject.addUpdateField(consegneMultipleInCorsoColumn, consegneMultipleInCorsoColumn+"-1");
  793.                
  794.                 if(ok != transazioneApplicativoServer.getDettaglioEsito() || transazioneApplicativoServer.getDataMessaggioScaduto()!=null) {
  795.                     /* UPDATE transazioni
  796.                      *      SET consegne_multiple=consegne_multiple-1,
  797.                      *          esito=esitoConsegnaMultiplaFallita  
  798.                      * WHERE (ESITO=esitoConsegnaMultipla OR ESITO=esitoConsegnaMultiplaInCorso OR ESITO=esitoConsegnaMultiplaFallita)
  799.                      */
  800.                     sqlQueryObject.addUpdateField(esitoColumn,"?");  
  801.                 }
  802.                 else {
  803.                      /* UPDATE transazioni
  804.                      *      SET consegne_multiple=consegne_multiple-1,
  805.                      *          esito = ( CASE
  806.                      *                    WHEN (consegne_multiple<=1 AND (esito=esitoConsegnaMultipla OR esito=esitoConsegnaMultiplaInCorso)) THEN esitoConsegnaMultiplaCompletata
  807.                      *                    WHEN (consegne_multiple>1 AND esito=esitoConsegnaMultipla) THEN esitoConsegnaMultiplaInCorso
  808.                      *                    ELSE  (ESITO)
  809.                      *                  END )
  810.                      * WHERE (ESITO=esitoConsegnaMultipla OR ESITO=esitoConsegnaMultiplaInCorso OR ESITO=esitoConsegnaMultiplaFallita)
  811.                      */
  812.                     Case caseValue = new Case(CastColumnType.INT, esitoColumn);
  813.                     caseValue.addCase(consegneMultipleInCorsoColumn+"<=? AND ("+esitoColumn+"=? OR "+esitoColumn+"=?)", "?");
  814.                     caseValue.addCase(consegneMultipleInCorsoColumn+">? AND "+esitoColumn+"=?", "?");
  815.                     sqlQueryObject.addUpdateField(esitoColumn, caseValue);
  816.                 }
  817.                
  818.             }
  819.            
  820.             sqlQueryObject.setANDLogicOperator(true);
  821.            
  822.             if(leftValue!=null && rightValue!=null) {
  823.                 sqlQueryObject.addWhereBetweenCondition(dataIngressoRichiestaColumn, false, "?", "?");
  824.             }
  825.            
  826.             sqlQueryObject.addWhereCondition(idTransazioneColumn+"=?");
  827.            
  828.             if(consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda) {
  829.                 sqlQueryObject.addWhereCondition(esitoColumn+"=?");
  830.             }
  831.             else {
  832.                 sqlQueryObject.addWhereCondition(false,
  833.                         esitoColumn+"=?",
  834.                         esitoColumn+"=?",
  835.                         esitoColumn+"=?");
  836.             }
  837.            
  838.             String updateCommand = sqlQueryObject.createSQLUpdate();
  839.             /**System.out.println("QUERY '"+updateCommand+"'");*/
  840.            
  841.             pstmt = connectionDB.prepareStatement(updateCommand);
  842.             int index = 1;
  843.             List<Object> params = new ArrayList<>();
  844.            
  845.             if(consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda) {
  846.                 pstmt.setInt(index++, esitoConsegnaMultiplaInCorso);
  847.                 params.add(esitoConsegnaMultiplaInCorso);
  848.             }
  849.             else {
  850.                 if(ok != transazioneApplicativoServer.getDettaglioEsito() || transazioneApplicativoServer.getDataMessaggioScaduto()!=null) {
  851.                     pstmt.setInt(index++, esitoConsegnaMultiplaFallita);
  852.                     params.add(esitoConsegnaMultiplaFallita);
  853.                 }
  854.                 else {
  855.                     // primo case
  856.                     pstmt.setInt(index++, 1); // il decremento nell'unico comando di update funziona transazionalmente; quindi quando lo porto a 0, il valore nella condizione è 1(lascio il <= per stare tranquillo)
  857.                     params.add(1);
  858.                     pstmt.setInt(index++, esitoConsegnaMultipla);
  859.                     params.add(esitoConsegnaMultipla);
  860.                     pstmt.setInt(index++, esitoConsegnaMultiplaInCorso);
  861.                     params.add(esitoConsegnaMultiplaInCorso);
  862.                     pstmt.setInt(index++, esitoConsegnaMultiplaCompletata);
  863.                     params.add(esitoConsegnaMultiplaCompletata);
  864.                     // secondo case
  865.                     pstmt.setInt(index++, 1);
  866.                     params.add(1);
  867.                     pstmt.setInt(index++, esitoConsegnaMultipla);
  868.                     params.add(esitoConsegnaMultipla);
  869.                     pstmt.setInt(index++, esitoConsegnaMultiplaInCorso);
  870.                     params.add(esitoConsegnaMultiplaInCorso);
  871.                 }
  872.             }
  873.            
  874.             if(leftValue!=null && rightValue!=null) {
  875.                 pstmt.setTimestamp(index++, leftValue);
  876.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(leftValue));
  877.                 pstmt.setTimestamp(index++, rightValue);
  878.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(rightValue));
  879.             }
  880.            
  881.             pstmt.setString(index++, transazioneApplicativoServer.getIdTransazione());
  882.             params.add(transazioneApplicativoServer.getIdTransazione());
  883.            
  884.             if(consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda) {
  885.                 pstmt.setInt(index++, esitoConsegnaMultipla);
  886.                 params.add(esitoConsegnaMultipla);
  887.             }
  888.             else {
  889.                 pstmt.setInt(index++, esitoConsegnaMultipla);
  890.                 params.add(esitoConsegnaMultipla);
  891.                 pstmt.setInt(index++, esitoConsegnaMultiplaInCorso);
  892.                 params.add(esitoConsegnaMultiplaInCorso);
  893.                 pstmt.setInt(index++, esitoConsegnaMultiplaFallita);
  894.                 params.add(esitoConsegnaMultiplaFallita);
  895.             }
  896.            
  897.             int row = pstmt.executeUpdate();
  898.             if(row!=1 &&
  899.                 logCore!=null) {
  900.                 String comandoSql = DBUtils.formatSQLString(updateCommand, params.toArray());
  901.                 String prefix = "Trovata transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"' ";
  902.                 if(row<1) {
  903.                     String msg = prefix+"per cui il comando di aggiornamento della transazione non ha comportato effetti: "+comandoSql;
  904.                     logCore.debug(msg);
  905.                 }
  906.                 else {
  907.                     throw new CoreException(prefix+"??");
  908.                 }
  909.             }
  910.            
  911.             /**String comandoSql = DBUtils.formatSQLString(updateCommand, params.toArray());
  912.             System.out.println("ROW: "+row+" (app:"+transazioneApplicativoServer.getConnettoreNome()+" id:"+transazioneApplicativoServer.getIdTransazione()+") sql:"+comandoSql);*/
  913.            
  914.             pstmt.close();
  915.             pstmt = null;
  916.            
  917.             // Chiusura Transazione
  918.             connectionDB.commit();
  919.            
  920.             return row;
  921.            
  922.         }catch(Throwable e) {
  923.            
  924.             try{
  925.                 if(pstmt != null) {
  926.                     pstmt.close();
  927.                     pstmt = null;
  928.                 }
  929.             } catch(Exception er) {
  930.                 // ignore
  931.             }
  932.             try{
  933.                 connectionDB.rollback();
  934.             } catch(Exception er) {
  935.                 // ignore
  936.             }
  937.            
  938.             throw new CoreException(e.getMessage(),e);
  939.         }finally{
  940.             try {
  941.                 if(pstmt!=null) {
  942.                     pstmt.close();
  943.                 }
  944.             }catch(Throwable t) {
  945.                 // ignore
  946.             }
  947.         }
  948.        
  949.     }
  950.     private static boolean existsTransazioneIniziataGestioneConsegnaAsincrona(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  951.             String tipoDatabase, Logger logCore,
  952.             int esitoConsegnaMultiplaInCorso, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata,
  953.             Timestamp leftValue, Timestamp rightValue) throws CoreException {
  954.    
  955.         ResultSet rs = null;
  956.         PreparedStatement pstmt = null;
  957.         try {
  958.        
  959.             TransazioneFieldConverter transazioneFieldConverter = new TransazioneFieldConverter(tipoDatabase);
  960.             String dataIngressoRichiestaColumn = transazioneFieldConverter.toColumn(Transazione.model().DATA_INGRESSO_RICHIESTA, false);
  961.             String idTransazioneColumn = transazioneFieldConverter.toColumn(Transazione.model().ID_TRANSAZIONE, false);
  962.             String esitoColumn = transazioneFieldConverter.toColumn(Transazione.model().ESITO, false);
  963.            
  964.             ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(tipoDatabase);
  965.            
  966.             String countAlias = "conteggio";
  967.             sqlQueryObject.addSelectCountField(idTransazioneColumn, countAlias);
  968.            
  969.             sqlQueryObject.addFromTable(CostantiDB.TRANSAZIONI);
  970.                        
  971.             sqlQueryObject.setANDLogicOperator(true);
  972.            
  973.             if(leftValue!=null && rightValue!=null) {
  974.                 sqlQueryObject.addWhereBetweenCondition(dataIngressoRichiestaColumn, false, "?", "?");
  975.             }
  976.            
  977.             sqlQueryObject.addWhereCondition(idTransazioneColumn+"=?");
  978.            
  979.             sqlQueryObject.addWhereCondition(false,
  980.                         esitoColumn+"=?",
  981.                         esitoColumn+"=?",
  982.                         esitoColumn+"=?");
  983.            
  984.             String queryCommand = sqlQueryObject.createSQLQuery();
  985.             /**System.out.println("QUERY '"+queryCommand+"'");*/
  986.            
  987.             pstmt = connectionDB.prepareStatement(queryCommand);
  988.             int index = 1;
  989.             List<Object> params = new ArrayList<>();
  990.                        
  991.             if(leftValue!=null && rightValue!=null) {
  992.                 pstmt.setTimestamp(index++, leftValue);
  993.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(leftValue));
  994.                 pstmt.setTimestamp(index++, rightValue);
  995.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(rightValue));
  996.             }
  997.            
  998.             pstmt.setString(index++, transazioneApplicativoServer.getIdTransazione());
  999.             params.add(transazioneApplicativoServer.getIdTransazione());
  1000.            
  1001.             pstmt.setInt(index++, esitoConsegnaMultiplaInCorso);
  1002.             params.add(esitoConsegnaMultiplaInCorso);
  1003.             pstmt.setInt(index++, esitoConsegnaMultiplaFallita);
  1004.             params.add(esitoConsegnaMultiplaFallita);
  1005.             pstmt.setInt(index++, esitoConsegnaMultiplaCompletata);
  1006.             params.add(esitoConsegnaMultiplaCompletata);
  1007.                        
  1008.             int count = 0;
  1009.             rs = pstmt.executeQuery();
  1010.             if(rs.next()) {
  1011.                 count = rs.getInt(countAlias);
  1012.             }
  1013.             else if(logCore!=null) {
  1014.                 String comandoSql = DBUtils.formatSQLString(queryCommand, params.toArray());
  1015.                 if(count<1) {
  1016.                     String msg = "Non trovata transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"' già in gestione: "+comandoSql;
  1017.                     logCore.debug(msg);
  1018.                 }
  1019.                 else {
  1020.                     throw new CoreException("Trovata più di una transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"' ??");
  1021.                 }
  1022.             }
  1023.            
  1024.             /**String comandoSql = DBUtils.formatSQLString(queryCommand, params.toArray());
  1025.             System.out.println("existsTransazioneIniziataGestioneConsegnaAsincrona Count: "+count+" (app:"+transazioneApplicativoServer.getConnettoreNome()+" id:"+transazioneApplicativoServer.getIdTransazione()+") sql:"+comandoSql);*/
  1026.            
  1027.             rs.close();
  1028.             rs = null;
  1029.             pstmt.close();
  1030.             pstmt = null;
  1031.            
  1032.             return count>0;
  1033.            
  1034.         }catch(Throwable e) {
  1035.            
  1036.             try{
  1037.                 if(rs != null) {
  1038.                     rs.close();
  1039.                     rs = null;
  1040.                 }
  1041.             } catch(Exception er) {
  1042.                 // ignore
  1043.             }
  1044.             try{
  1045.                 if(pstmt != null) {
  1046.                     pstmt.close();
  1047.                     pstmt = null;
  1048.                 }
  1049.             } catch(Exception er) {
  1050.                 // ignore
  1051.             }
  1052.             try{
  1053.                 connectionDB.rollback();
  1054.             } catch(Exception er) {
  1055.                 // ignore
  1056.             }
  1057.            
  1058.             throw new CoreException(e.getMessage(),e);
  1059.         }finally{
  1060.             try{
  1061.                 if(rs != null) {
  1062.                     rs.close();
  1063.                 }
  1064.             } catch(Exception er) {
  1065.                 // ignore
  1066.             }
  1067.             try {
  1068.                 if(pstmt!=null) {
  1069.                     pstmt.close();
  1070.                 }
  1071.             }catch(Throwable t) {
  1072.                 // ignore
  1073.             }
  1074.         }
  1075.        
  1076.     }
  1077.    
  1078.     private static int getEsitoTransazione(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  1079.             String tipoDatabase, Logger logCore,
  1080.             Timestamp leftValue, Timestamp rightValue) throws CoreException {
  1081.    
  1082.         PreparedStatement pstmt = null;
  1083.         ResultSet rs = null;
  1084.         try {
  1085.        
  1086.             TransazioneFieldConverter transazioneFieldConverter = new TransazioneFieldConverter(tipoDatabase);
  1087.             String dataIngressoRichiestaColumn = transazioneFieldConverter.toColumn(Transazione.model().DATA_INGRESSO_RICHIESTA, false);
  1088.             String idTransazioneColumn = transazioneFieldConverter.toColumn(Transazione.model().ID_TRANSAZIONE, false);
  1089.             String esitoColumn = transazioneFieldConverter.toColumn(Transazione.model().ESITO, false);
  1090.            
  1091.             ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(tipoDatabase);
  1092.            
  1093.             sqlQueryObject.addFromTable(CostantiDB.TRANSAZIONI);
  1094.            
  1095.             sqlQueryObject.addSelectField(esitoColumn);
  1096.            
  1097.             sqlQueryObject.setANDLogicOperator(true);
  1098.            
  1099.             if(leftValue!=null && rightValue!=null) {
  1100.                 sqlQueryObject.addWhereBetweenCondition(dataIngressoRichiestaColumn, false, "?", "?");
  1101.             }
  1102.            
  1103.             sqlQueryObject.addWhereCondition(idTransazioneColumn+"=?");
  1104.                        
  1105.             String select = sqlQueryObject.createSQLQuery();
  1106.             /**System.out.println("QUERY '"+select+"'");*/
  1107.            
  1108.             pstmt = connectionDB.prepareStatement(select);
  1109.             int index = 1;
  1110.             List<Object> params = new ArrayList<>();
  1111.            
  1112.             if(leftValue!=null && rightValue!=null) {
  1113.                 pstmt.setTimestamp(index++, leftValue);
  1114.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(leftValue));
  1115.                 pstmt.setTimestamp(index++, rightValue);
  1116.                 params.add(org.openspcoop2.utils.date.DateUtils.getSimpleDateFormatMs().format(rightValue));
  1117.             }
  1118.            
  1119.             pstmt.setString(index++, transazioneApplicativoServer.getIdTransazione());
  1120.             params.add(transazioneApplicativoServer.getIdTransazione());
  1121.                        
  1122.             rs = pstmt.executeQuery();
  1123.             int esitoReturn = -1;
  1124.             while(rs.next()) {
  1125.                
  1126.                 int found = rs.getInt(esitoColumn);
  1127.                
  1128.                 if(logCore!=null) {
  1129.                     String comandoSql = DBUtils.formatSQLString(select, params.toArray());
  1130.                     if(esitoReturn<0) {
  1131.                         esitoReturn = found;
  1132.                     }
  1133.                     else {
  1134.                         rs.close();
  1135.                         pstmt.close();
  1136.                         throw new CoreException("Trovata più di una transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"' ?? (query: "+comandoSql+")");
  1137.                     }
  1138.                 }
  1139.             }
  1140.            
  1141.             /**String comandoSql = formatSQLString(updateCommand, params.toArray());
  1142.             System.out.println("ROW: "+row+" (app:"+transazioneApplicativoServer.getConnettoreNome()+" id:"+transazioneApplicativoServer.getIdTransazione()+") sql:"+comandoSql);*/
  1143.            
  1144.             rs.close();
  1145.             pstmt.close();
  1146.             pstmt = null;
  1147.                        
  1148.             connectionDB.commit(); // anche se si tratta di una read, serve per non far rimanere aperta la transazione
  1149.            
  1150.             return esitoReturn;
  1151.            
  1152.         }catch(Throwable e) {
  1153.            
  1154.             try{
  1155.                 if(rs != null) {
  1156.                     rs.close();
  1157.                     rs = null;
  1158.                 }
  1159.             } catch(Exception er) {
  1160.                 // ignore
  1161.             }
  1162.             try{
  1163.                 if(pstmt != null) {
  1164.                     pstmt.close();
  1165.                     pstmt = null;
  1166.                 }
  1167.             } catch(Exception er) {
  1168.                 // ignore
  1169.             }
  1170.             try{
  1171.                 connectionDB.rollback();
  1172.             } catch(Exception er) {
  1173.                 // ignore
  1174.             }
  1175.            
  1176.             throw new CoreException(e.getMessage(),e);
  1177.         }finally{
  1178.             try{
  1179.                 if(rs != null) {
  1180.                     rs.close();
  1181.                     rs = null;
  1182.                 }
  1183.             } catch(Exception er) {
  1184.                 // ignore
  1185.             }
  1186.             try {
  1187.                 if(pstmt!=null) {
  1188.                     pstmt.close();
  1189.                 }
  1190.             }catch(Throwable t) {
  1191.                 // ignore
  1192.             }
  1193.         }
  1194.        
  1195.     }
  1196.    
  1197.     public static boolean existsTransaction(String idTransaction, Connection connectionDB,
  1198.             String tipoDatabase, Logger logCore, boolean connectionDBCommit) throws CoreException {
  1199.    
  1200.         PreparedStatement pstmt = null;
  1201.         ResultSet rs = null;
  1202.         try {
  1203.        
  1204.             if(logCore!=null) {
  1205.                 // nop
  1206.             }
  1207.            
  1208.             TransazioneFieldConverter transazioneFieldConverter = new TransazioneFieldConverter(tipoDatabase);
  1209.             String idTransazioneColumn = transazioneFieldConverter.toColumn(Transazione.model().ID_TRANSAZIONE, false);
  1210.            
  1211.             ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(tipoDatabase);
  1212.            
  1213.             sqlQueryObject.addFromTable(CostantiDB.TRANSAZIONI);
  1214.            
  1215.             sqlQueryObject.addSelectField(idTransazioneColumn);
  1216.            
  1217.             sqlQueryObject.setANDLogicOperator(true);
  1218.            
  1219.             sqlQueryObject.addWhereCondition(idTransazioneColumn+"=?");
  1220.                        
  1221.             String select = sqlQueryObject.createSQLQuery();
  1222.             /**System.out.println("QUERY '"+select+"'");*/
  1223.            
  1224.             pstmt = connectionDB.prepareStatement(select);
  1225.             int index = 1;
  1226.             List<Object> params = new ArrayList<>();
  1227.            
  1228.             pstmt.setString(index++, idTransaction);
  1229.             params.add(idTransaction);
  1230.                        
  1231.             rs = pstmt.executeQuery();
  1232.             boolean esitoReturn = rs.next();

  1233.             /**String comandoSql = formatSQLString(updateCommand, params.toArray());
  1234.             System.out.println("Esists: "+esitoReturn+" (app:"+transazioneApplicativoServer.getConnettoreNome()+" id:"+transazioneApplicativoServer.getIdTransazione()+") sql:"+comandoSql);*/
  1235.            
  1236.             rs.close();
  1237.             pstmt.close();
  1238.             pstmt = null;
  1239.                        
  1240.             if(connectionDBCommit) {
  1241.                 connectionDB.commit(); // anche se si tratta di una read, serve per non far rimanere aperta la transazione
  1242.             }
  1243.            
  1244.             return esitoReturn;
  1245.            
  1246.         }catch(Throwable e) {
  1247.            
  1248.             try{
  1249.                 if(rs != null) {
  1250.                     rs.close();
  1251.                     rs = null;
  1252.                 }
  1253.             } catch(Exception er) {
  1254.                 // ignore
  1255.             }
  1256.             try{
  1257.                 if(pstmt != null) {
  1258.                     pstmt.close();
  1259.                     pstmt = null;
  1260.                 }
  1261.             } catch(Exception er) {
  1262.                 // ignore
  1263.             }
  1264.             try{
  1265.                 connectionDB.rollback();
  1266.             } catch(Exception er) {
  1267.                 // ignore
  1268.             }
  1269.            
  1270.             throw new CoreException(e.getMessage(),e);
  1271.         }finally{
  1272.             try{
  1273.                 if(rs != null) {
  1274.                     rs.close();
  1275.                     rs = null;
  1276.                 }
  1277.             } catch(Exception er) {
  1278.                 // ignore
  1279.             }
  1280.             try {
  1281.                 if(pstmt!=null) {
  1282.                     pstmt.close();
  1283.                 }
  1284.             }catch(Throwable t) {
  1285.                 // ignore
  1286.             }
  1287.         }
  1288.        
  1289.     }
  1290.    
  1291.     @Deprecated
  1292.     private static void serializableModeAggiornaInformazioneConsegnaTerminataEngine(TransazioneApplicativoServer transazioneApplicativoServer, Connection connectionDB,
  1293.             String tipoDatabase, Logger logCore,
  1294.             IDAOFactory daoFactory, Logger logFactory, ServiceManagerProperties smpFactory,
  1295.             boolean debug,
  1296.             int esitoConsegnaMultipla, int esitoConsegnaMultiplaFallita, int esitoConsegnaMultiplaCompletata, int ok,
  1297.             boolean consegnaInErroreRilevatoEsitoTransazioneConsegnaInCoda,
  1298.             long gestioneSerializableDBAttesaAttiva, int gestioneSerializableDBCheckInterval) throws CoreException {
  1299.        
  1300.         /*
  1301.           Viene realizzato con livello di isolamento SERIALIZABLE, per essere sicuri
  1302.           che esecuzioni parallele non leggano dati inconsistenti.
  1303.           Con il livello SERIALIZABLE, se ritorna una eccezione, deve essere riprovato
  1304.           La sincronizzazione e' necessaria per via del possibile accesso simultaneo del servizio Gop
  1305.           e del servizio che si occupa di eliminare destinatari di messaggi
  1306.          */
  1307.         // setAutoCommit e livello Isolamento
  1308.         int oldTransactionIsolation = -1;
  1309.         try{
  1310.             oldTransactionIsolation = connectionDB.getTransactionIsolation();
  1311.             /** già effettuato fuori dal metodo connectionDB.setAutoCommit(false);*/
  1312.             JDBCUtilities.setTransactionIsolationSerializable(tipoDatabase, connectionDB);
  1313.         } catch(Exception er) {
  1314.             throw new CoreException("(setIsolation) "+er.getMessage(),er);
  1315.         }

  1316.         PreparedStatement pstmt = null;
  1317.         ResultSet rs = null;
  1318.         boolean updateEffettuato = false;
  1319.        
  1320.         long scadenzaWhile = DateManager.getTimeMillis() + gestioneSerializableDBAttesaAttiva;
  1321.        
  1322.         CoreException coreException = null;
  1323.         while(!updateEffettuato && DateManager.getTimeMillis() < scadenzaWhile){

  1324.             try{    
  1325.                 IDAOFactory daoF = daoFactory;
  1326.                 Logger log = logFactory;
  1327.                 ServiceManagerProperties smp = smpFactory;
  1328.                
  1329.                 org.openspcoop2.core.transazioni.dao.jdbc.JDBCServiceManager jdbcServiceManager =
  1330.                         (org.openspcoop2.core.transazioni.dao.jdbc.JDBCServiceManager) daoF.getServiceManager(org.openspcoop2.core.transazioni.utils.ProjectInfo.getInstance(),
  1331.                                 connectionDB, false,
  1332.                                 smp, log);
  1333.                 jdbcServiceManager.getJdbcProperties().setShowSql(debug);
  1334.                 JDBCTransazioneService transazioneService = (JDBCTransazioneService) jdbcServiceManager.getTransazioneService();
  1335.                
  1336.                 transazioneService.enableSelectForUpdate();
  1337.                
  1338.                 IPaginatedExpression pagExpression = transazioneService.newPaginatedExpression();
  1339.                 pagExpression.equals(Transazione.model().ID_TRANSAZIONE, transazioneApplicativoServer.getIdTransazione());
  1340.                 List<Map<String, Object>> l = null;
  1341.                 try {
  1342.                     l = transazioneService.select(pagExpression, Transazione.model().ESITO, Transazione.model().CONSEGNE_MULTIPLE_IN_CORSO);
  1343.                 }catch (NotFoundException notfound) {}
  1344.                 if(l!=null && !l.isEmpty()) {
  1345.                     if(l.size()>1) {
  1346.                         coreException = new CoreException("Trovata più di una transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"'");
  1347.                     }
  1348.                     else {
  1349.                                                
  1350.                         Object oEsito = l.get(0).get(Transazione.model().ESITO.getFieldName());
  1351.                         int esito = -1;
  1352.                         if(oEsito instanceof Integer) {
  1353.                             esito = (Integer) oEsito;
  1354.                         }
  1355.                        
  1356.                         Object oConsegneMultiple = l.get(0).get(Transazione.model().CONSEGNE_MULTIPLE_IN_CORSO.getFieldName());
  1357.                         int consegneMultiple = -1;
  1358.                         if(oConsegneMultiple instanceof Integer) {
  1359.                             consegneMultiple = (Integer) oConsegneMultiple;
  1360.                         }
  1361.                                                
  1362.                         String prefix = "Trovata transazione con id '"+transazioneApplicativoServer.getIdTransazione()+"'";
  1363.                         if(esitoConsegnaMultipla == esito || esitoConsegnaMultiplaFallita == esito) {
  1364.                             int decrement = consegneMultiple-1;
  1365.                             UpdateField uFieldConsegneMultipleInCorso = new UpdateField(Transazione.model().CONSEGNE_MULTIPLE_IN_CORSO, decrement);
  1366.                             UpdateField uFieldEsito = null;
  1367.                             if(esitoConsegnaMultipla == esito) {
  1368.                                 // non appena c'è un errore, marca la transazione come fallita
  1369.                                 if(ok != transazioneApplicativoServer.getDettaglioEsito() || transazioneApplicativoServer.getDataMessaggioScaduto()!=null) {
  1370.                                     uFieldEsito = new UpdateField(Transazione.model().ESITO, esitoConsegnaMultiplaFallita);
  1371.                                 }
  1372.                                 else if(decrement<=0) {
  1373.                                     uFieldEsito = new UpdateField(Transazione.model().ESITO, esitoConsegnaMultiplaCompletata);
  1374.                                 }
  1375.                             }
  1376.                             if(uFieldEsito!=null) {
  1377.                                 transazioneService.updateFields(transazioneApplicativoServer.getIdTransazione(), uFieldConsegneMultipleInCorso, uFieldEsito);
  1378.                             }
  1379.                             else {
  1380.                                 transazioneService.updateFields(transazioneApplicativoServer.getIdTransazione(), uFieldConsegneMultipleInCorso);
  1381.                             }
  1382.                         }
  1383.                         else if(esitoConsegnaMultiplaCompletata == esito) {
  1384.                             if(logCore!=null) {
  1385.                                 String msg = prefix+", con un esito '"+esito+"' (ConsegnaMultiplaCompletata) già gestita da un altro nodo";
  1386.                                 logCore.debug(msg);
  1387.                             }
  1388.                         }
  1389.                         else {
  1390.                             coreException = new CoreException(prefix+", con un esito '"+esito+"' non atteso");
  1391.                         }

  1392.                        
  1393.                     }
  1394.                 }

  1395.                 transazioneService.disableSelectForUpdate();
  1396.                
  1397.                 // Chiusura Transazione
  1398.                 connectionDB.commit();

  1399.                 // ID Costruito
  1400.                 updateEffettuato = true;

  1401.             } catch(Throwable e) {
  1402.                 try{
  1403.                     if(rs != null)
  1404.                         rs.close();
  1405.                 } catch(Exception er) {
  1406.                     // ignore
  1407.                 }
  1408.                 try{
  1409.                     if(pstmt != null)
  1410.                         pstmt.close();
  1411.                 } catch(Exception er) {
  1412.                     // ignore
  1413.                 }
  1414.                 try{
  1415.                     connectionDB.rollback();
  1416.                 } catch(Exception er) {
  1417.                     // ignore
  1418.                 }
  1419.             }

  1420.             if(!updateEffettuato){
  1421.                 // Per aiutare ad evitare conflitti
  1422.                 try{
  1423.                     Utilities.sleep(getRandom().nextInt(gestioneSerializableDBCheckInterval)); // random da 0ms a checkIntervalms
  1424.                 }catch(Exception eRandom){
  1425.                     // ignore
  1426.                 }
  1427.             }
  1428.         }
  1429.         // Ripristino Transazione
  1430.         try{
  1431.             connectionDB.setTransactionIsolation(oldTransactionIsolation);
  1432.             /** già effettuato fuori dal metodo connectionDB.setAutoCommit(true);*/
  1433.         } catch(Exception er) {
  1434.             throw new CoreException("(ripristinoIsolation) "+er.getMessage(),er);
  1435.         }

  1436.         if(coreException!=null) {
  1437.             throw coreException;
  1438.         }
  1439.     }
  1440. }