Hibernate 自动提交
碰到一个同事没有用@Transactional声明事务,数据库还是提交了。感觉奇怪,测试验证了一下,记录一下
代码:
@Transactional
publicvoidaddSe(){
Sese=newSe();
se.setName("test");
commonDao.getHibernateTemplate().save(se);String a = null;
a.length();//抛异常
Sese1=newSe();
se1.setName("test111");
commonDao.getHibernateTemplate().save(se1);
}
配置:
<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<propertyname="driverClassName"value="oracle.jdbc.OracleDriver"/>
<propertyname="url"value="jdbc:oracle:thin:@1.1.1.1:1521:a"/>
<propertyname="username"value="a"/>
<propertyname="password"value="1"/>
</bean><tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<propertyname="sessionFactory"ref="sessionFactory"/>
<propertyname="dataSource"ref="dataSource"/>
</bean><bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="hibernateProperties">
<props>
<propkey="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<propkey="hibernate.show_sql">true</prop>
<propkey="hibernate.connection.autocommit">false</prop>
<propkey="hibernate.cache.use_second_level_cache">false</prop>
<propkey="hibernate.cache.use_query_cache">false</prop>
</props>
</property>
<propertyname="packagesToScan">
<list>
<value>cn.test</value>
</list>
</property>
</bean>
加@Transactional的情况下,由于回滚,两条记录都没有写进数据库,即有事务并回滚
去掉@Transactional后,第一条记录入库,第二条没有入库;即两次操作不在一个事务中,但第一个操作的操作自动提交了跟踪了一下connection的atuoCommit,刚被创建时atuoCommit为true,
如果配置了@Transactional,org.hibernate.transaction.JDBCTransaction在事务开始时将自动提交设置为false;
事务结束或者回滚后再设置为原始的状态。
publicvoidbegin()throwsHibernateException{
if(begun){
return;
}
if(commitFailed){
thrownewTransactionException("cannotre-starttransactionafterfailedcommit");
}log.debug("begin");
try {
toggleAutoCommit=jdbcContext.connection().getAutoCommit();
if(log.isDebugEnabled()){
log.debug("currentautocommitstatus:"+toggleAutoCommit);
}
if(toggleAutoCommit){
log.debug("disablingautocommit");
jdbcContext.connection().setAutoCommit(false);
}
}
不过<propkey="hibernate.connection.autocommit">false</prop>好像不起作用;
查了一下代码,hibernate.connection.autocommit在DriverManagerConnectionProvider创建连接的时候用到,
但这个执行过程没有用到DriverManagerConnectionProvider,根据配置是org.springframework.jdbc.datasource.DriverManagerDataSource完成创建连接的动作
不清楚是否还有其他地方用到了这个配置