首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring同步方法不同步

Spring同步方法不同步
EN

Stack Overflow用户
提问于 2014-03-13 12:30:18
回答 2查看 5.2K关注 0票数 4

环境:

  • apache tomcat 7
  • java 7
  • oracle 11g
  • 月食
  • 2.1
  • 春天
  • 冬眠 我正在开发一个web应用程序,它接收来自客户端的请求,并根据请求类型为它们生成序列号以供进一步处理。为了生成唯一的序列号,我有一种方法从DB获取当前序列号并将其增加1,然后用新的序列号更新记录。

职能:

代码语言:javascript
复制
    @Transactional
public synchronized Long generateSequenseNumber(String requestType) {
     //get current sequence number for this requestType
            //increment it by one
            //update it in DB

}

该函数运行良好,但问题是,当我从压力测试工具(JMeter)调用应用程序每秒发送50个请求时,我会得到以下异常:

代码语言:javascript
复制
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [

尽管函数是同步的。

任何建议都会有帮助。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-13 12:34:11

问题是@Transactional在进入同步方法之前开始会话,并在方法完成后提交更改,因此对数据库的更改不会在同步方法中应用。

请查看Spring @Transactional 10.5.1节。

您可以尝试在调用此方法时添加同步块,而不是使其同步:

代码语言:javascript
复制
synchronized(this){
   generateSequenseNumber();
}
票数 7
EN

Stack Overflow用户

发布于 2014-03-13 12:50:39

延伸了Azizi的答案。

@Transactional使Spring在AOP代理中包装类。然后将目标方法执行包装在事务拦截器中。因此,总体呼吁是这样的:

代码语言:javascript
复制
-> FooProxy#generateSequenseNumber
   -> TransactionInterceptor#invoke
      -> BEGIN TRANSACTION
         -> Foo#generateSequenceNumber (synchronized)
      -> COMMIT|ROLLBACK TRANSACTION

您可以(和what )尝试在方法中放置断点以查看堆栈上的内容。

如果要解决generateSequenseNumber方法中的同步问题,则可以使用TransactionTemplateREQUIRES_NEW传播。当然,这样@Transactional注释就没有意义了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22378707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档