Sql server 在服务层jpa上应用@Transactional(propagation=propagation.REQUIRED)时,无法从应用程序以及ms sql客户端读取表
我们在应用程序端使用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.xmlSql 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表中
<!-- 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)