2017-03-09 3 views
0

Ich verwende CDI, um Verbindung in meine DAO-Klassen injizieren.j2ee injected Verbindung nicht Transaktion verwaltet

Die Verbindung Produzent ist wie folgt:

public class ConnectionManager { 
    private static final Logger LOGGER = Logger.getLogger(ConnectionManager.class.getName()); 

    @Resource(mappedName = "java:/PostgresXADS") 
    private DataSource flamingoDs; 

    @Named("flamingoConnection") 
    @Produces 
    @RequestScoped 
    public Connection createFlamingoConnection() { 
     LOGGER.info("createFlamingoConnection called"); 
     try { 
      return flamingoDs.getConnection(); 
     } catch (SQLException e) { 
      throw new RuntimeException(e); 
     } 
    } 
    public void closeConnection(@Disposes Connection c) { 
     LOGGER.info("closeConnection called"); 
     try { 
      c.close(); 
     } catch (SQLException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

Dann in meiner DAO-Klasse zum Beispiel habe ich:

public class GraphDao { 

@Inject 
@Named("flamingoConnection") 
Connection con; 

public String createObjNode(String tipoCod, String nome, Object flmNodeData) 
     throws JsonProcessingException, SQLException, IllegalArgumentException { 
    if (tipoCod == null || flmNodeData == null || nome == null) { 
     throw new IllegalArgumentException("Empty parameters"); 
    } 
    LOGGER.info("createObjNode start"); 
    String generatedUuid; 
    String sql = "INSERT INTO graphdb.nodo_oggetto (tipo_cod, nome, dati) VALUES(?, ? ,?) RETURNING uuid"; 
    PGobject jsonObject = getJsonPgObj(flmNodeData); 
    try (PreparedStatement stmt = this.con.prepareStatement(sql);) { 
     stmt.setObject(1, tipoCod); 
     stmt.setString(2, nome); 
     stmt.setObject(3, jsonObject); 
     try (ResultSet rs = stmt.executeQuery()) { 
      rs.next(); 
      generatedUuid = rs.getString(1); 
     } 
    } 
    LOGGER.info("createObjNode end"); 
    return generatedUuid; 
} 

ich die dao Methode innerhalb einer ejb Methode bin Aufruf mit Container verwaltet Transaktion .

Die Verbindung wird injiziert und im Bereich des aktuellen Threads korrekt geschlossen, aber nachdem eine Abfrage ausgeführt wurde, wird sie sofort in der Datenbank ausgeführt.

Die Datenquelle i bin mit vom Typ XA es Definition ist:

<xa-datasource jndi-name="java:/PostgresXADS" pool-name="PostgresXADS" enabled="true" use-ccm="true"> 
    <xa-datasource-property name="url"> 
     jdbc:postgresql://localhost:5433/infostud?ApplicationName=NewSegr 
    </xa-datasource-property> 
    <driver>postgres</driver> 
    <xa-pool> 
     <prefill>true</prefill> 
     <is-same-rm-override>false</is-same-rm-override> 
     <no-tx-separate-pools>true</no-tx-separate-pools> 
     <wrap-xa-resource>true</wrap-xa-resource> 
    </xa-pool> 
    <security> 
     <user-name>XXX</user-name> 
     <password>XXX</password> 
    </security> 
    <validation> 
     <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/> 
     <background-validation>true</background-validation> 
     <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/> 
    </validation> 
</xa-datasource> 
<drivers> 
    <driver name="postgres" module="org.postgresql"> 
     <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class> 
     <datasource-class>org.postgresql.ds.PGPoolingDataSource</datasource-class> 
</driver> 

Ich bin unsing postgresql und Wildfly 10

Kann jemand bitte erklären Sie mir, warum es passiert?

Sorry für mein schlechtes Englisch

+0

Können Sie ein Beispiel nennen, wo Sie diese 'createObjNode nennen() 'und es verpflichtet sich sofort zur Datenbank? – ytg

Antwort

0

Da Sie Zugriff auf die Verbindungs ​​Instanz haben, können Sie versuchen, das zu auf false gesetzt autocommit?

Connection conn = flamingoDs.getConnection(); 
conn.setAutoCommit(false); 
return conn; 

Nach dem doc wird standardmäßig auf true gesetzt.

By the way, ich glaube, Sie nicht die Verbindung in einem CDI Hersteller produzieren sollten, sondern es in den Try-mit-Ressourcen erstellen:

try (Connection connection = dataSource.getConnection(); 
      PreparedStatement stmt = connection.prepareStatement(sql)) 
Verwandte Themen