Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I config to turn off autocommit in Spring + JDBC?

I am using Spring with JDBC and found that it is autocommit.

How can I config to turn it off in spring-servlet.xml?

This is my current configuration:

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
    p:driverClassName="${jdbc.driverClassName}"
    p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
    p:password="${jdbc.password}" />

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>
like image 409
Surasin Tancharoen Avatar asked Mar 10 '12 19:03

Surasin Tancharoen


People also ask

Does JDBC template auto-commit?

JDBC drivers turn on auto-commit mode for new database connections by default. When it's on, they automatically run each individual SQL statement inside its own transaction. Besides using this default setting, we can also turn on auto-commit manually by passing true to the connection's setAutoCommit method: connection.

What is use of setAutoCommit () in JDBC?

In this scenario you can use the setAutoCommit() method. This method belongs to the Connection interface and, it accepts a boolean value. If you pass true to this method it turns on the auto-commit feature of the database and, if you pass false to this method it turns off the auto-commit feature of the database.

What does @transactional do in spring?

The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.

Does spring @transactional lock table?

"@Transactional" as itself on any isolation level doesn't enabling any locking. To achieve locking behaviour you should use "@Lock" annotation or use " for update" in your query.


2 Answers

It seems that my configuration missed this line:

<tx:annotation-driven transaction-manager="txManager"/>

Then, in my service classes, I use @Transactional annotation. For example

@Service
class CompanyServiceImpl implements CompanyService{
    @Autowired
    private CompanyDAO companyDAO;

    @Transactional
    public void addCompany(Company company) {
            companyDAO.addCompany(company); // in here, there is JDBC sql insert
            companyDAO.addCompany_fail(company); // just for test
    }
}

If there is a exception happening in the addCompany_fail(), the first addCompany() one will also be rollbacked.

I followed this document to understand idea how transaction controlled in Spring. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

I followed this document to understand how to code with JDBC in Spring. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html

I also read this (Free) http://www.infoq.com/news/2009/04/java-transaction-models-strategy. It is really good one. And I feel the same with the writer that most people do not understand (or care) about transaction.

PS: Seem that many people misunderstand that using such Hibernate/Spring framework is only for avoid complexity of JDBC and Transaction Control. Many people think like "JDBC and Transaction are so complex, just use Hibernate and forget about those two". Many examples on the internet about Spring+Hibernate or Spring+JDBC seemingly not care about transaction at all. I feel that this is a bad joke. Transaction is too serious for just letting something handle it without truly understanding.

Hibernate and Spring is so powerful and so complex. Then, as someone said, "Great power comes with responsibilities".

UPDATE: 2013-08-17: There are good example about transaction here http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial. However, this is not explain that if you want to use REQUIRES_NEW, why you need to create another class (otherwise you will get this problem Spring Transaction propagation REQUIRED, REQUIRES_NEW , which it seems REQUIRES_NEW does not really create a new transaction)

Update: 2018-01-01: I have created a full example with Spring Boot 1.5.8.RELEASE here https://www.surasint.com/spring-boot-database-transaction-jdbi/ and some basic experiment examples here https://www.surasint.com/spring-boot-connection-transaction/

like image 55
Surasin Tancharoen Avatar answered Oct 11 '22 23:10

Surasin Tancharoen


Try defaultAutoCommit property. Code would look like this:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:defaultAutoCommit="false" />

Look at javadoc: http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html#defaultAutoCommit

like image 31
kapeloland Avatar answered Oct 11 '22 22:10

kapeloland