I'm writing a Clojure program using clojure.java.jdbc. I'm using DBCP to pool connections to HSQL 2.2.8. I have a (transaction) block in which I test if a schema exists, and if not, creates it and a bunch of tables. One of the statements after the schema create (I believe a MERGE statement) throws a BatchUpdateException.
The issue is that the schema create is not rolled back on the BatchUpdateException, even though they're part of the same (transaction) block.
Are there known issues with Clojure JDBC interacting with DBCP or HSQL?
Never mind.
Transactions don't apply to schema changes, apparently. WTF?
Related
I have a JUnit 5 testcase which is annotated with #Transactional and it is calling save service (which uses JPA saveandFlush) first, and trying to retrieve the same data/entity by using find service, which is using plain JDBC for searching, but it is not able to find that entity.
When I tried using isolation of the transaction as read_uncommitted it threw exception saying "java.sql.SQLException: READ_COMMITTED and SERIALIZABLE are the only valid transaction levels" please note that I am using Oracle database.
Is there any other way we can read the data which is present in same transaction by JDBC code?
Oracle does not implement Read Uncommited isolation level, so you will not be able to see uncommited changes from other sessions.
As Mark Rotteveel and Marmite Bomber said, two different transactions/connections(JPA and JDBC) can not see each other's uncommitted data, specially for application having Oracle database.
I had to use spring managed jdbc template so that JPA and the JDBC template uses the same transaction and data is visible to each other.
For my upcoming microservice deployments I intend to use spring-boot and Flyway as the database migration tool. For security reasons I need to draw a line between the DDL schema creation parts (create, alter, drop table etc.) and accessing the DML data (select, insert, update, delete) stored inside the Oracle db.
I was thinking of using two different datasources, the first used solely for Flyway operations and the second for the real application.
I havent't found a best practise implementation to solve this problem yet. Any advice or link would be very helpful.
We are using JPA/Hibernate for project where we need to insert, say 10000 records in database with multiple joins/relations etc. The functionality is fine but the performance is really slow.
Just wondering if migrating to JDBC will help in some performance gain?
Thanks,
-csn
You can do batch inserts with JPA/Hibernate - see "Batch processing".
You would almost certainly get better performance by doing batch inserts in JDBC (addBatch(), etc), but the Hibernate method may be more desirable if your schema is complex.
If you use JDBC batches, make sure that you do all of your addBatch() calls in a transaction.
If you happen to be using MySQL, be sure to add rewriteBatchedStatements=true to your connection parameters.
I have a very interesting situation. I am slightly new to JBoss and Oracle, having worked mostly with Weblogic on DB2. That said, what I am trying to do is pretty simple.
I have a local-tx-datasource to an Oracle database. From my Java I code, I invoke datasource.getConnection() after retrieving the datasource using the appropriate JNDI name. The local-tx-datasource declaration in my -ds.xml file does not have any explicit reference to autocommit behaviour.
After getting the connection, I execute a create/update query and I get back the correct update count. Subsequently, for a short duration, I am even able to retrieve this record. However, after that the database pretends it never got the record in the first place, and there is nothing at all.
My experience with connections suggests that this happens when the connection does not commit its work, and so only that connection itself will be able to see the data in its transaction. From what I read, JBoss too follows the specification that the Connection returned is an autocommit one. I even verified this from my Java code, and it states the autocommit behaviour is set to true. However, if that was the case, why are my records not getting created / updated?
Following this, I set the Connection's autocommit behaviour to false (again from Java code), and then did the commit explicitly. Since then, there has been no issue.
What could possibly be going wrong? Is my understanding of autocommit here incorrect or does JBoss have some other interpretation of it. Please note, I do not have any transactions at all. These are very simple single record insert queries.
Please note, I do not have any transactions at all.
Wrong assumption. The local-tx-datasource starts a JTA transaction in your behalf. I'm not sure how the autocommit works in this scenario, but I suppose that autocommit applies only when you are using exclusively JDBC transactions, not JTA transactions.
In JTA, if you don't commit a transaction[*], it will be rolled back after the timeout. This explains the scenario that you are experiencing. So, I'd try to either change the local-tx-datasource to no-tx-datasource or to manually commit the transaction.
Note, however, that not managing your transactions is a bad thing. Autocommit should always be avoided. There's no better party to determine when to commit than your application. Leaving this responsibility to the driver/container is, IMO, not very responsible :-)
[*] One exception is for operations inside EJBs, whose business methods are "automatically" wrapped in a JTA transaction. So, you don't need to explicitly commit the transaction.
I'm using Jetty with mysql. I need some basic transaction support, and jetty is warning me at startup that no transaction manager is in use. I thought transactions were native to mysql? I'm trying something like:
Connection conn = ...;
conn.setAutoCommit(false);
// insert into table foo some data
// insert into table grok some data
conn.commit();
If an exception is thrown between the two statements, I see that data has made its way into table "foo", so the transaction calls did not work.
So I guess we really do need a transaction manager here, am I understanding this correctly? If so, I was looking at bitronix: http://docs.codehaus.org/display/BTM/Home
Thanks
Transactions are not "native" to MySQL (unlike other databases).
You need to make sure you are using the InnoDB storage engine, otherwise you won't be able to make use of transactions.