我有一个 Spring 服务方法,可以在同一个表上执行两个数据库操作。一个使用 Hibernate Session Factory,另一个使用普通的 Spring JDBC。但是,我希望将两者绑定(bind)到一个事务中。使用下面的代码,看起来创建了 2 个不同的事务,第一个事务为第二个事务锁定了表。
如何确保这两个操作都在单个事务下。 ?
我的服务等级
@Service
public class MyService{
@Autowired
IMyDao mydao;
@Transactional
public void myMethod(){
...
mydao.save(entity); //This uses hibernate
...
mydao.saveBulk(List<Entity> entities>; //This uses spring jdbc for performance reasons.
}
...
}
MyDAOImpl.class
public class MyDAOImpl extends SimpleJDBCSupport implements IMyDao{
private SessionFactory sessionFactory;
@Autowired
public MyDAOImpl (
@Qualifier("sessionFactory") final SessionFactory sessionFactory,
@Qualifier("dataSource") final DataSource dataSource) {
this.sessionFactory = sessionFactory;
this.setDataSource(dataSource);
}
public void save(Entity entity){
sessionFactory.getCurrentSession().createQuery("insert into tableA... " ).executeUpdate() ;
}
public void saveBulk(List<Entity> entites){
...// prepare batch insert data.
this.getJdbcTemplate().batchUpdate("insert into tableA... " , batchPreparedStmtSetter)
}
}
Spring 配置
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean">
<property name="xaDataSourceClassName" value="${advdb.jdbc.dataSourceClassName}" />
<property name="xaProperties" ref="dataSourceProperties" />
<property name="uniqueResourceName" value="${advdb.jdbc.uniqueResourceName}" />
<property name="testQuery" value="${advdb.jdbc.testQuery}" />
<property name="minPoolSize" value="${advdb.jdbc.minPoolSize}" />
<property name="maxPoolSize" value="${advdb.jdbc.maxPoolSize}" />
<property name="maxIdleTime" value="${advdb.jdbc.maxIdleTime}" />
<property name="borrowConnectionTimeout" value="${advdb.jdbc.borrowConnectionTimeout}" />
<property name="reapTimeout" value="${advdb.jdbc.reapTimeout}" />
<property name="maintenanceInterval" value="${advdb.jdbc.maintenanceInterval}" />
</bean>
<!-- Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource- ref="dataSource">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
...
...
</bean>
最佳答案
事务边界由所使用的连接控制。只要您使用相同的连接(可以是相同的 Hibernate Session 实例、相同的 JPA 实体管理器实例或相同的 Spring JdbcTemplate),在当前连接上的事务提交或回滚之前,在此连接中独占锁定的表将不可用于其他连接。
就您而言,由于您使用不同的连接(通过 HibernateSession
和 SimpleJdbcTemplate
)进行正常保存和批量保存,因此它们不能属于同一事务。这两个 Action 必须一个接一个地串行进行。
关于java - 在同一个表的同一事务中绑定(bind) springjdbc 和 hibernate session 工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13314562/