Sql server 在服务层jpa上应用@Transactional(propagation=propagation.REQUIRED)时,无法从应用程序以及ms sql客户端读取表

Sql server 在服务层jpa上应用@Transactional(propagation=propagation.REQUIRED)时,无法从应用程序以及ms sql客户端读取表,sql-server,spring,hibernate,jpa,Sql Server,Spring,Hibernate,Jpa,我们在应用程序端使用Spring、Hibernate和JPA,MS SQL Server作为数据库,JBOSS 6.4.0作为应用服务器 应用程序中有两种不同的服务。一个服务使用@Transactional(propagation=propagation.REQUIRED)插入/更新某些数据库表中的数据,另一个服务使用@Transactional(propagation=propagation.SUPPORTS)从相同的数据库表读取数据。问题-当第一个服务正在运行时,第二个服务无法从这些DB表中

我们在应用程序端使用Spring、Hibernate和JPA,MS SQL Server作为数据库,JBOSS 6.4.0作为应用服务器

应用程序中有两种不同的服务。一个服务使用@Transactional(propagation=propagation.REQUIRED)插入/更新某些数据库表中的数据,另一个服务使用@Transactional(propagation=propagation.SUPPORTS)从相同的数据库表读取数据。问题-当第一个服务正在运行时,第二个服务无法从这些DB表中读取数据。DB表似乎被锁定,因为我们甚至无法从SQL Server客户端访问这些表。这里的服务是指Spring服务类。我们不存在两个服务都可以同时在DB表中写入数据的情况。因此,目的是在服务1在表中插入/更新数据时,能够使用服务2从表中读取数据

服务1-Cron作业服务层

服务2-UI服务层

下面是配置

applicationContext.xml

<!-- JPA EntityManagerFactory Setup Begin -->
    <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!-- <property name="persistenceUnitName" value="myPersistenceUnit" /> -->
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.XXX.ccp.dao" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <!-- <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
        </property> -->
    </bean>
    <!-- JPA EntityManagerFactory Setup End -->


    <!-- JPA TransactionManager Setup End -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven />
    <!-- JPA TransactionManager Setup End -->

    <bean id="persistenceExceptionTranslationPostProcessor"
        class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
UI服务层->

 @Transactional(propagation = Propagation.SUPPORTS, readOnly=true)
        public List<DeviceDataSynchDTO> getAllCarrierAndDbSynchStatus()  throws CCPDaoException{//code goes here}
@Transactional(传播=propagation.SUPPORTS,只读=true)
公共列表GetAllCarrierAndBSynchStatus()引发CCPDaoException{//code go here}
为了在JPA中运行查询,我们使用下面的persistanceContext 私人实体管理者实体管理者

请让我知道,如果我需要提供进一步的细节


任何帮助都将不胜感激。

请提供一些代码,我的最佳猜测是,在调用read方法时,第一个事务没有提交(即注释为@transaction的方法尚未完成)

只读方法可以进行注释

@Transactional(readOnly=true)

希望这有帮助。

我对MSSql不太熟悉。我怀疑的是整张桌子被锁上了,而不是整排。默认情况下,它是一个行级别锁。当会话/事务超过约5000个行级别锁时,锁将升级到表级别锁(或分区级别,如果已分区表)。如果服务1(cron作业)在单个事务中连续插入/更新大量记录,则您可能必须控制它


Ref

谢谢您的回复。我已经申请了readOnly=“true”。请让我知道您希望我共享代码的哪一部分?写入事务完成后,任何锁都将被释放。在完成之前,读取事务将无法查看写入事务中的内容。我认为关键是确保在读之前完成写操作。请记住,事务注释不会对mineral方法调用生效。我没有得到任何解决方案。解决方法-我已经将@transnational移动到Dao层来解决这个问题。通过缩小事务范围,我可以从同一个表中读取数据。
 @Transactional(propagation = Propagation.SUPPORTS, readOnly=true)
        public List<DeviceDataSynchDTO> getAllCarrierAndDbSynchStatus()  throws CCPDaoException{//code goes here}
@Transactional(readOnly=true)