环境:
职能:
@Transactional
public synchronized Long generateSequenseNumber(String requestType) {
//get current sequence number for this requestType
//increment it by one
//update it in DB
}该函数运行良好,但问题是,当我从压力测试工具(JMeter)调用应用程序每秒发送50个请求时,我会得到以下异常:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [尽管函数是同步的。
任何建议都会有帮助。谢谢。
发布于 2014-03-13 12:34:11
问题是@Transactional在进入同步方法之前开始会话,并在方法完成后提交更改,因此对数据库的更改不会在同步方法中应用。
请查看Spring @Transactional 10.5.1节。
您可以尝试在调用此方法时添加同步块,而不是使其同步:
synchronized(this){
generateSequenseNumber();
}发布于 2014-03-13 12:50:39
延伸了Azizi的答案。
@Transactional使Spring在AOP代理中包装类。然后将目标方法执行包装在事务拦截器中。因此,总体呼吁是这样的:
-> FooProxy#generateSequenseNumber
-> TransactionInterceptor#invoke
-> BEGIN TRANSACTION
-> Foo#generateSequenceNumber (synchronized)
-> COMMIT|ROLLBACK TRANSACTION您可以(和what )尝试在方法中放置断点以查看堆栈上的内容。
如果要解决generateSequenseNumber方法中的同步问题,则可以使用TransactionTemplate和REQUIRES_NEW传播。当然,这样@Transactional注释就没有意义了。
https://stackoverflow.com/questions/22378707
复制相似问题