I am using HikariCP for connection pooling. I have tried setting autoCommit to both true and false. Still my transactions are not getting
rollbacked when an exception occur.
I have tried the same with org.apache.commons.dbcp.BasicDataSource. Transactions are getting rollbacked properly with this datasource but
not when com.zaxxer.hikari.HikariDataSource is configured.
I'm using MySQL InnoDB database engine.
Edit:
@Service
@Transactional(rollbackFor = { Exception.class })
public class AServiceImpl {
@Override
public SomeDTO signUpUser(SomeDTO someDTO) throws Exception {
Company company = addCompany();
User user = addUser();
------------
}
private Company addCompany()
try{
return companyRepository.addCompany();
} catch(PersistenceException e){
//throws exception
}
}
@Override
public User addUser()
try{
return userRepository.addUser();
}catch(PersistenceException e){
//throws exception
}
}
Here, exception occurs at addUser method and records inserted through addCompany method isn't rollbacked
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maximumPoolSize" value="100" />
<property name="idleTimeout" value="900000" />
<property name="connectionTimeout" value="2000" />
<property name="minimumIdle" value="20" />
<property name="maxLifetime" value="1800000" />
<property name="leakDetectionThreshold" value="60000" />
<property name="autoCommit" value="false" />
<property name="dataSourceProperties">
<props>
<prop key="prepStmtCacheSize">300</prop>
<prop key="prepStmtCacheSqlLimit">2048</prop>
<prop key="cachePrepStmts">true</prop>
<prop key="useServerPrepStmts">true</prop>
<prop key="useLocalSessionState">true</prop>
<prop key="useLocalTransactionState">true</prop>
<prop key="rewriteBatchedStatements">true</prop>
<prop key="cacheResultSetMetadata">true</prop>
<prop key="cacheServerConfiguration">true</prop>
<prop key="elideSetAutoCommits">false</prop>
<prop key="maintainTimeStats">true</prop>
<prop key="useLocalTransactionState">true</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
HikariCP version: 3.1.0
JDK version : 1.8.0_162
Database : MySQL InnoDB
MySQLJDBCDriver version : 5.1.31
Looking for some solutions. Thanks in advance.
How do you know that transactions are not being rolled back?
If autoCommit=false and the transaction state is dirty, HikariCP will automatically rollback on Connection.close(). If debug logging is enabled, you should see it logged. If you do not see the log message, that implies that Spring is explicitly calling rollback() (or commit()) before calling close() -- as I would expect with the annotation above.
Try setting useLocalTransactionState to false and see whether it makes a difference.
Attention: your configuration is currently setting this property twice! Remove one of the duplicate lines with <prop key="useLocalTransactionState">true</prop> and then change the remaining one to set the property to false instead of true.
Why I recommend this: I just spent a day trying to figure out why my transactions do not get rolled back. I found out that it's connected to the useLocalTransactionState property. If I set useLocalTransactionState to true my transactions do not get rolled back although, my debugging and p6spy clearly show that a rollback is performed by my transaction manager.
There is the MySQL Connector/J bug #75209 that describes something similar. Although that bug claims to be fixed with MySQL Connector/J v5.1.40, I can still see similar behaviour for v5.1.40 and v8.0.13.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With