we use Weblogic server and always set autoCommit to 'false' when getting Connection to Oracle 10g.
I want to know if there is a setting in Weblogic wherein it will automatically Commit transactions if a Commit or Rollback is not explicitly called from within application code. I heard similar setting exists in Websphere.
It looks like you are not using either Container-managed or Bean-managed transactions. Or, for that matter, you are merely retrieving a connection from a DataSource and then disabling autocommit, without the initial establishment a transaction context; this implies that you are using JDBC transactions (that rely on the transaction manager of the underlying database).
When you use Container or Bean managed transactions, you will no longer have to worry about the autocommit property of a Connection used in a transaction, as the container will ensure that the autocommit property is set to false, before returning the Connection to the application.
If you need to use Container-managed transactions, you'll need to use EJBs. Any transaction associated with an EJB will commit automatically, unless a RuntimeException or an ApplicationException is thrown.
If you need to use Bean-managed or programmatic transactions, you will have to use the UserTransaction API.
If you are using an ORM framework like Hibernate that is responsible for establishing connections, then you ought to remember that it is Hibernate that is responsible for switching off the autocommit property of the Connection. and in most cases, it would switch off the property.
If you intend to use JDBC transactions, despite the better alternative of JTA transactions, then you could attempt to set the defaultAutoCommit property for the driver, from either Admin Console, or in the JDBC configuration file of the Datasource. The snippet of the JDBC configuration file is shown below:
<?xml version='1.0' encoding='UTF-8'?>
<jdbc-data-source xmlns="http://xmlns.oracle.com/weblogic/jdbc-data-source" xmlns:sec="http://xmlns.oracle.com/weblogic/security" xmlns:wls="http://xmlns.oracle.com/weblogic/security/wls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/jdbc-data-source http://xmlns.oracle.com/weblogic/jdbc-data-source/1.0/jdbc-data-source.xsd">
<name>JDBC Data Source-Oracle</name>
<jdbc-driver-params>
<url>jdbc:oracle:thin:#localhost:1521:oracle</url>
<driver-name>oracle.jdbc.OracleDriver</driver-name>
<properties>
<property>
<name>user</name>
<value>app</value>
</property>
<!-- Disable autocommit for connections-->
<property>
<name>defaultAutoCommit</name>
<value>false</value>
</property>
</properties>
...
In the Administration Console, you may add the defaultAutoCommit=false property in the Properties textarea of the DataSource configuration:
The connections configured inside of a connection pool on the App Server are not really closed when you call the connection.close() method, they are actually returned back to the connection pool, and can be used by the next requesting object. Not sure if the DataSource connection pools will track if there are uncommitted changes on a connection being returned to the pool and perform an auto commit or rollback on it?
Setting autoCommit to false is the right thing to do.
All RDBMS that I know of commit the transaction at the end unless explicitly rolled back. Do you see a different behavior? If you suspect something is wrong, one option is to turn on logging in the database server, where you would be able to see the commit request. I am afraid I don't know how to do it in Oracle.
Logging in app server may not be useful because it too may not be issuing explicit commit
Related
I'm trying to check the database connection with jpa using the EntitityManager/Session class.
To check both cases (connected/not connected), I simply start/deactivate the service mysql before running the code.
Asking simple sql queries to the database is out of mind since it doesn't cover all cases.
I already tried:
Session session = entityManager.unwrap(Session.class)
session.isConnected();
But that always returns true...
When I disable the mySQL service I want session.isConnected() to return false, but it always returns true;
Is there any other way to check for the database connection(using any other classes maybe)?
Short answer: don't
Long answer: if you're developing an application where this is important, you will probably be using some sort of database connection pooling framework, like the
Tomcat JDBC pool
Apache Commons DBCP
HikariCP
C3P0 Connection pool
This will manage many important aspects for you, including connection lifecycle. In tomcat jdbc for example you can specify:
testOnBorrow="true"
validationQuery="select 1 from sysibm.dual"
This on an IBM DB2 database will test whether a connection went stale every time you use it, and also swap it out for a fresh one if the select fails. Done this way, you will never have to worry about this on the level of you application code.
I have a spring (version 3.2.15) application that uses more than one connection in a transactional method.
My use case is:
Call to transactional method (which opens one connection)
Query for an entity (which opens and closes another connection)
Persist the entity
End of the method (closes the first connection)
The problem is that I have a limited number of connections, and I need to ensure that only one connection is used per transactional method. This problem causes a dead lock in my application because there are much more transactions opened than the number of connections available.
Is there any way that I can use the same connection spring uses to maintain the transaction on my method? I have already tried the hibernate option hibernate.connection.release_mode in after_statement mode, but an error occurs when hibernate is trying to commit the transaction.
I've read the spring transaction documentation but I cannot figure out how to configure spring to behave this way.
I am writing a JEE7 application that runs in WebSphere Liberty Profile 8.5.5. We are using JPA (which is implemented via Eclipselink in WLP).
I have multiple persistence units in the same 'persistence.xml' file. I also need to access two of those units in the same class.
I am getting a runtime error when I try to use the second EntityManager:
#PersistenceContext(unitName = "wwer-list")
private EntityManager entityManagerWwerList;
#PersistenceContext(unitName = "main-dashboard")
private EntityManager entityManagerMainDashboard;
E WTRN0062E: An illegal attempt to use multiple resources that have only one-phase capability has occurred within a global transaction.
How do I get rid of this error?
Also, all of the tables I am using are only needed for reading. So how can I specify that I only want read-only access to JPA?
This issue is prompting because one of your datasource configured as (single phase commit) using ConnectionPoolDataSource and other is configured with XADataSource.
If you want to continue with the same datasource configuration, you will have to update your Server configuration to "Acccept Heuristic Hazard".
In the admin console, click the EAR, select the check box "Accept heuristic hazard". Re-start the server.
This link to enable the Last Participant Support may also help.
http://www.ibm.com/support/knowledgecenter/SSAW57_7.0.0/com.ibm.websphere.nd.doc/info/ae/webui_pme/ui/ueac_laoextensionsettings.html
I can't tell for sure without your persistence.xml and server.xml configurations, but it looks like the <dataSource> elements backing your <persistence-unit> configurations are not XA capable.
By default, a <dataSource> should be a javax.sql.XADataSource (and therefore XA capable), however if you are using a JDBC driver that does not provide an XADataSource implementation, Liberty will pick a simpler DataSource implementation (i.e. javax.sql.ConnectionPoolDataSource or plain javax.sql.DataSource).
A global transaction is whenever you issue a UserTransaction.begin() and lasts until you issue a commit() or a rollback(). There are other ways that you can get into a global transaction too.
Since you want read-only access, converting your DataSources to XA would probably be overkill. Instead, try to eliminate the global transactions from the equation. If you can't eliminate the global transactions, you can specify XADataSource in your server.xml in the following way:
<dataSource type="javax.sql.XADataSource" ...>
<jdbcDriver .../>
<properties .../>
</dataSource>
My application has long running transactions and hence I tried the option session.close() at the end of every method to ensure that the connection objects are not held indefinitely for long time.
When session.close() option is used, I could see that the Hibernate's session object and the corresponding Connection object obtained from session.connection() are destroyed properly. But the issue is with the connection pool. The connection obtained by the session is not released back to the connection pool even after closing the session. Other requests are found waiting for connection from the pool.
I am using JTA transaction in my application. In hibernate.cfg.xml, I have set connection.release_mode to auto (default) and connection.autocommit to true.
Has anyone faced this issue? Please let me know what am I missing here.
Follow-up: This is my hibernate configuration file details:
<property name="connection.datasource">MXoraDS</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.release_mode">after_statement</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.JTASessionContext</property>
<property name="transaction.auto_close_session">true</property>
<property name="max_fetch_depth">2</property>
We use JSF and EJB 2.1 at the application layer connecting to Oracle DB. The after_statement doesn't seem to release the connection to the pool. Please let me know if u need any more details.
I am using JTA transaction in my application. In hibernate.cfg.xml, I have set connection.release_mode to auto (default) and connection.autocommit to true.
Could you try to define the hibernate.connection.release_mode property to after_statement explicitly? I know this is supposed to be the default but, depending on your context (could you be using Spring?), auto might not behave as expected (see here and here).
For reference, here is what the Table 3.4. Hibernate JDBC and Connection Properties writes about the property hibernate.connection.release_mode:
Specifies when Hibernate should
release JDBC connections. By default,
a JDBC connection is held until the
session is explicitly closed or
disconnected. For an application
server JTA datasource, use
after_statement to aggressively
release connections after every JDBC
call. For a non-JTA connection, it
often makes sense to release the
connection at the end of each
transaction, by using
after_transaction. auto will
choose after_statement for the JTA
and CMT transaction strategies and
after_transaction for the JDBC
transaction strategy.
e.g. auto (default) | on_close | after_transaction |
after_statement
This setting only affects Sessions
returned from
SessionFactory.openSession. For
Sessions obtained through
SessionFactory.getCurrentSession, the
CurrentSessionContext implementation
configured for use controls the
connection release mode for those
Sessions. See Section 2.5,
“Contextual sessions”
If it doesn't help, please add more details about your environment and configuration (Spring?), how you get the session, etc.
if you are using the JDBCTransactionManager, the connection will be returned to the connectionpool when the transactions ends.
We are migrating a JDBC based application to JPA and EJB3. Our old application used the Connect#setClientInfo API to record the current user name as part of the client info:
http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html#setClientInfo%28java.lang.String,%20java.lang.String%29
We need to do something similar in the EJB3 project. How?
We can use EJB3 interceptors around the EJB service calls in order to capture the current user and set it as info on the datasource. However, I see problems with this. I think there is no guarantee when the JPA flush() occurs. If you set the client info in an interceptor, make some updates, and then return, the flush() and actual database write may not occur until well after your bean (and interceptor) are out of scope. Is this correct?
I believe JPA and EntityManagers are abstractions over the connection, and you cannot reliable set the client info on the connection. True or false?
What JPA provider are you using?
EclipseLink has support for user based connection, Oracle proxy connections and VPD. EclipseLink also defines Session and connection level events that allow you to set configuration on the JDBC connection.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing