In Glassfish, there is a JDBC Pool option called
Non Transactional Connections
So am I correct in thinking that "Non Transactional Connections" is the same as setting auto-commit=false ?
If that is correct, then why, when this option is disabled (i.e. non-transactional enabled) do I get an error saying
org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled.
This is when I have java code that looks like :
try {
preparedStatement = connection.prepareStatement(.....);
preparedStatement.executeQuery();
connection.commit();
}
Non Transactional Connections does not set the autoCommit property to false by default. That's not what non - transactional connections are for. From the Oracle glassfish documentation below,
The main advantage of using non-transactional connections is that the overhead incurred in enlisting and delisting connections in transaction contexts is avoided. However, use such connections carefully. For example, if a non-transactional connection is used to query the database while a transaction is in progress that modifies the database, the query retrieves the unmodified data in the database. This is because the in-progress transaction hasn’t committed. For another example, if a non-transactional connection modifies the database and a transaction that is running simultaneously rolls back, the changes made by the non-transactional connection are not rolled back.
You should
Connection con = ds.getConnection();
boolean initValue = con.getAutoCommit();
con.setAutoCommit(false);
//do your work here and commit or rollback
con.setAutoCommit(initValue );
Related
I have spring boot application, that makes update in two database Postgres. I use Atomikos for distributed transaction management.
I see that my application makes query in both database each 10 seconds:
"SELECT gid FROM pg_prepared_xacts where database = current_database()"
I'm wonder why? Has atomikos some property for changing period? For example 1 minute. What will be if query returns some gids?
I had looked internet hard about this question, but didn't find the answer.
I have some assumption, and I want to know the right answer.
Why does Atomikos ping pg_prepared_xacts?
It calls "recovery scan" and aim is recovering after failing of application, or error in application. Because of it, in database will not be "orphaned" prepared transactions created by Atomikos.
Has atomikos some property for changing period?
Yes, it has: com.atomikos.icatch.recovery_delay. Other useful properties are here: JtaProperties
What will be if query returns some gids?
Atomikos checks if returned gids are in atomikos transaction log and have status "to commit". If it's so, he will commit prepare transactions, else he will rollback transactions. Note, that Atomikos will handle prepare transactions, that were created by him, and will not handle other prepare transactions.
I'm using Spring-tx-4.0.9 in a multithreaded application and have a problem with "stalled" transaction after the thread is killed by OutOfMemory.
Each thread ask PlatformTransactionManager (implementation org.springframework.jdbc.datasource.DataSourceTransactionManager) to get an transaction via TransactionTemplate Propagation is REQUIRED. This template has a timeout set. State of a transaction is managed by application and after all, work is done, then thread calls commit. This returns a transaction back to the PlatformTransactionManager, and almost every time releases connection to the DB (in DB, the session for this connection is mostly released)
But if the thread is killed by OutOfMemory, then the underlying transaction is returned to internal transaction pool and another thread can acquire this "broken" transaction. This transaction has the timeout set from the first time and cannot be reset even if new thread call TM to get transaction with new TransactionTemplate. So after this timeout expires, every request on transaction throws TransactionTimedOutException.
Only available methods on PlatformTransactionManager are getTransaction, commit and rollback.
Method getTransaction can return new or previous transaction. From returned instance of TransactionStatus, I'm able to detect new or stalled transaction, but I'm unable to release it.
Method rollback sets flag isRollbackOnly, but the transaction is still not released and getTransaction returns stalled. If I then call commit as recommended by JavaDoc, then nothing changed and the transaction is still hanged.
If I use propagation REQUIRES_NEW, then "broken" transaction is suspended, which solve a problem with TransactionTimedOutException, but an old transaction is still hanged and holds the connection to the DB (unwanted state).
Is there a way, how to proper release a broken transaction (rollback and release connection)?
EDIT- Current code for getting a TransactionalStatus
public TransactionStatus beginTransaction() {
// transaction begin
logger.debug("Create new transaction.");
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.setTimeout(txConnectionTimeout);
TransactionStatus txStatus = transactionManager.getTransaction(template);
logger.debug(
"Transaction created. TransactionStatus: isCompleted=" + txStatus.isCompleted() + ", isNewTransaction=" +
txStatus.isNewTransaction());
return txStatus;
}
that's a question which has confuse me a lot.
for example:
when I design the Dao layer,sometimes,I must do some insert operation,and than
I should do some query such as select the data's id by auto-generate in db.
my question was that:
when I use spring to help manage datasource,
when I do more than two sql operation one by one,
how many times the java client connect to the db?? only one ? or more?
code,such as fellows:
getSimpleJdbcTemplate().update(some params...);
getSimpleJdbcTemplate().query(some params...);
It depends on your Transactional settings.
Spring-transactions in local mode, work on a thread-local connection for all the db activities within single transaction.
If you have not configured transactions, then basically each DB call will retrieve connection from datasource using Datasource.getConnection()
In terms client connecting to DB, if you are using datasource with connection pooling capability, then connections are returned from the pool.
But if datasource is not backed by pool, then it will instantiate connection to DB server on demand ( on getConnection() ) call
How many connection will hold for a single hibernate session where there is only one DB?
there is one connection per session.
the connection is opened only if the session needs to send JDBC queries
you should avoid using the underlying connection. The connection() method has been deprecated. If you need to perform raw jdbc operations, use the doWork(..) method (if your hibernate version is the latest)
At a given time given session will only hold one connection
which you can access with the connect() method.
The connection used can be changed though using the reconnect() method.
I am pretty new on the ORM's. I just start to read books and documents about Java Persistence API with Hibernate.
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
Should we close it after every persist/update/delete or not? If we don't close it, will the database connection stay opened?
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
This is not exactly true but closing an EntityManagerFactory would be closer to destroying a whole connection pool. If you want to think JDBC connection, you should think EntityManager.
Should we close it after every persist/update/delete or not?
Creating an EntityManagerFactory is a pretty expensive operation and should be done once for the lifetime of the application (you close it at the end of the application). So, no, you should not close it for each persist/update/delete operation.
The EntityManagerFactory is created once for all and you usually get an EntityManager per request, which is closed at the end of the request (EntityManager per request is the most common pattern for a multi-user client/server application).
If we don't close it, will the database connection stay opened?
As hinted, it's the EntityManager that is actually associated to a database connection and closing the EntityManager will actually release the JDBC connection (most often, return it to a pool).