我有一个Spring服务方法,它在同一个表上执行两个数据库操作。一个使用Hibernate Session Factory,另一个使用普通的Spring JDBC。但是,我希望两者都绑定到一个事务中。使用下面的代码,看起来创建了两个不同的事务,第一个事务将表锁定为第二个事务。
如何确保两个操作都在单个事务中。 ?
我的服务类
@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)
}
}
弹簧配置
<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>
答案 0 :(得分:1)
事务边界由使用的连接控制。只要您使用相同的连接(可以是相同的Hibernate Session实例,相同的JPA实体管理器实例或相同的Spring JdbcTemplate),在当前连接上的事务之前,其他人无法使用在此连接中独占锁定的表是承诺还是回滚。
在您的情况下,由于您使用不同的连接(通过HibernateSession
和SimpleJdbcTemplate
)进行正常保存和批量保存,因此它们不能属于同一事务。这两个动作必须一个接一个地序列化。