我们正在使用 Spring 4.0.0、Hibernate 4.2.8 和 Ms SQL Server 8 开发一个应用程序,它使用由 DB 表支持并与 Hibernate VO (CustomSequence) 映射的自定义序列
在服务调用中访问此序列:
- 主服务启动自己的事务
- 执行代码,做一些事情,查询......
为序列值调用序列服务 (SequenceService)
SequenceService 启动自己的事务(REQUIRES_NEW)
SequenceService 找到对象,返回值并保存下一个值
主服务获取值,设置业务对象并保存(此时序列值已由内部新事务提交)
- 出口
管理自定义序列的服务片段:
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
@Service("sequenceService")
public class SequenceService implements ISequenceService {
@Autowired
private ISequenceDao sequenceDao;
private Integer getSequence() {
CustomSequence sequenceOut = sequenceDao.find();
final Integer nextVal = sequenceOut.getNextVal();
sequenceOut.setNextVal(nextVal + 1);
sequenceDao.save(sequenceOut);
return nextVal;
}
}
我们的问题是 serializable 属性被完全忽略,所以 2 个并发线程访问 getSequence 方法并获得相同的值。
如果我们使用 TransactionSynchronizationManager 检查隔离,则该值对于可序列化(值 = 8)似乎是正确的:
...
Integer isolation = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
...
我们的 spring xml 文件是这个:
<context:annotation-config />
<context:component-scan base-package="dev.app"/>
<tx:annotation-driven />
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/appDatasource"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="false" >
<property name="dataSource"> <ref bean="dataSource" /></property>
<property name="packagesToScan" value="dev.app.model"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!-- Disable LOB creation as connection -->
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
</props>
</property>
</bean>
我已经使用这些命令检查了 MS SQL Management Studio 的数据库可序列化功能,然后执行了应用程序代码,并且它工作了(在工作室提交之前阻止代码):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
UPDATE CUSTOM_SEQUENCE set NEXTVAL = 1000;
WAITFOR DELAY '00:1:00'
COMMIT
¿关于发生了什么的任何线索?我在互联网上阅读了很多信息,但无济于事
非常感谢提前!