数据库中有1000条数据.
现在有10个财务.
每个财务请求获取10条数据.
我为了防止这10个财务在同时获得一样的数据.
我想问一下spring有这样的机制嘛?
就是说同时10个人发了10个请求过来.
但是action只有一个而且action是一个一个处理请求.
如:处理第一个的时候其他9个都处于等待的状态.只有第一个从action中出去了,才接待第二个.
以此类推.
spring可以这样设置吗?
如果不能这样的话我只能手动去同步了.
27 个解决方案
#1
好像没有同步请求的,不知道你有没有试过在Service层得查询业务上设置方法同步呢?应为Service是单例的,即使10个请求同时发生,在Service层同一时刻只有一个请求能进入查询业务。这样应该就能实现同步了吧。
#2
这不行吧.
#3
没有直接这样的机制,不过Spring对于bean默认都是单例模式,所以你只要在函数上增加一个 synchronized 关键字,就全部都同步掉了。
#4
EJB
@Singleton
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class Service implements ServiceLocal {
@Override
@Lock(LockType.WRITE)
public void doSomething() {
}
}
#5
我刚才也想过这种形式.
就是bean本身就是单例的
然后在方法中增加synchronized 同步化
但是他真的能做到我在帖子里说到的那种吗?
我有点怀疑.所以来问问大家.
#6
只要肯定是单例,就没问题。
如果你无法确定是单例,那么就让该函数再调用一个 private static synchronized xxoo()
不过,我重新看了下你的问题,我觉得可能存在一个误区:
“如:处理第一个的时候其他9个都处于等待的状态.只有第一个从action中出去了,才接待第二个”
并不等同于:
“防止这10个财务在同时获得一样的数据”
因为即便你轮流执行10次:Select Top 10 * From 表; 实际上每次你还是得到相同的结果啊。
#7
给你的Controller类 写个空构造方法 , 打个断点。
看每次请求的时候,是否会实例化。
看每次请求的时候,是否会实例化。
#8
同步你的service方法就可以了
#9
我取了10条数据之后会修改状态.
如:我要查询状态==1的.
等第一个人获取到数据之后我会把状态改成==2
第二个人来查询的时候还是以状态==1来查询.
这样的话应该是没问题的吧.
#10
哦,如果这样是没问题的。
其实如果你把这个过程做为一个完整事务来处理的话,数据库层面都可以控制住相互之间不冲突。
#11
交给事务吧,事务的四个特性保证完成任务。
#12
【完整事务来处理】什么意思啊?
数据库层面都可以控制住相互之间不冲突?
又啥意思啊?还有别的方法嘛?说说呗.
#13
楼主对数据库事务不太熟悉么?
如果是JDBC的话,首先关闭自动提交,然后做Select数据时:
Select Top 10 * From ... For Update
然后对ResultSet进行修改(updateXXOO),最后 commit();
数据库为了保证事务一致性,会把你所选择出来的记录集锁定住(行锁或表锁),这样就控制住并发了。
如果是JDBC的话,首先关闭自动提交,然后做Select数据时:
Select Top 10 * From ... For Update
然后对ResultSet进行修改(updateXXOO),最后 commit();
数据库为了保证事务一致性,会把你所选择出来的记录集锁定住(行锁或表锁),这样就控制住并发了。
#14
我用的Struts2+Spring+Hibernate
#15
这个是可以的.我的框架里面带着事物控制的.如果出错会全部回滚.
我用的hibernate+杭锁就可以了.
#16
http://wangxr66.iteye.com/blog/1469077
我看到这篇文章中最后说道了一句话
"在Struts2与Spring集成时,配置Action的Bean时一定记得加上scope属性,值为:prototype,否则会有线程安全问题。 "
我要是把他设置成单例的话会有线程安全问题吗?
我有点蒙了.
我看到这篇文章中最后说道了一句话
"在Struts2与Spring集成时,配置Action的Bean时一定记得加上scope属性,值为:prototype,否则会有线程安全问题。 "
我要是把他设置成单例的话会有线程安全问题吗?
我有点蒙了.
#17
它说的是Action的“Bean”,如果所有请求都共享一个“Bean”,那不是死定了。。。
#18
晕...下我一跳...我把他的话看成了Action...如果吧Action设置成了prototype的话不就没啥用了嘛...
我在在数据查询和更新的时候增加了hibernate事物,就怕在做更新数据库状态操作的时候出现错误...
不过估计应该不会出错误...
action已经是单例了在加上synchronized
已经可以了
万一出现错误了还有事物可以去控制回滚一下...
这就足够了吧.
#19
可以使用Spring+jms+queue
#20
为什么不能获得同样的数据?
我没看出来你的业务场景,以及可预见的代码中存在线程安全问题
我没看出来你的业务场景,以及可预见的代码中存在线程安全问题
#21
如果获得同样的数据的话多个财务对一条数据做处理的话,首先工作重复了,而且最后如果出错了
也不好找到相应的责任人.
所以要避免数据被同时操作.
#22
理论上是绝对够了的。
不过我补充下:
数据库层面的控制是最合理且安全的,而且基本上就以数据库实现为准。
synchronized的潜在问题是:集群。如果你的部署环境是集群环境,那么synchronized可没法在多个JVM之间保证同步;所以你看到,为啥我说数据库层面控制才是最安全的。
所以,为了避免编码级的疏漏,你要故意做些测试,控制好两个请求同时去操作数据库(比如在Select之后增加Sleep(10000),然后再做其它处理,然后继续Sleep(10000),然后再提交)。
关键性设计和实现必须得到验证,否则从技术人员角度来说,是不严谨的做事方法。
#23
我这里暂时不会集群.
而且我加了hibernate的事物如果出现错误了就直接回滚了,不返回给页面数据了.而是提示他有错误了.
数据库方面实现的话要如何实现呢?我这里用的是mysql
简单提一下吧谢谢
#24
数据库层面控制就是我13楼说的,Select的时候就要加锁。
不过我对Hibernate不太熟悉,没研究过怎么实现选择时加锁。
不过我对Hibernate不太熟悉,没研究过怎么实现选择时加锁。
#25
哦```知道了
我研究一下...看看在数据库层面怎么弄...
谢了...
#26
数据同时操作可以使用乐观锁或者悲观锁就行了,没必要这样进行同步的
#27
我了解一下
回头再开个帖子大家聊聊
这个锁的问题吧.
#1
好像没有同步请求的,不知道你有没有试过在Service层得查询业务上设置方法同步呢?应为Service是单例的,即使10个请求同时发生,在Service层同一时刻只有一个请求能进入查询业务。这样应该就能实现同步了吧。
#2
这不行吧.
#3
没有直接这样的机制,不过Spring对于bean默认都是单例模式,所以你只要在函数上增加一个 synchronized 关键字,就全部都同步掉了。
#4
EJB
@Singleton
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class Service implements ServiceLocal {
@Override
@Lock(LockType.WRITE)
public void doSomething() {
}
}
#5
我刚才也想过这种形式.
就是bean本身就是单例的
然后在方法中增加synchronized 同步化
但是他真的能做到我在帖子里说到的那种吗?
我有点怀疑.所以来问问大家.
#6
只要肯定是单例,就没问题。
如果你无法确定是单例,那么就让该函数再调用一个 private static synchronized xxoo()
不过,我重新看了下你的问题,我觉得可能存在一个误区:
“如:处理第一个的时候其他9个都处于等待的状态.只有第一个从action中出去了,才接待第二个”
并不等同于:
“防止这10个财务在同时获得一样的数据”
因为即便你轮流执行10次:Select Top 10 * From 表; 实际上每次你还是得到相同的结果啊。
#7
给你的Controller类 写个空构造方法 , 打个断点。
看每次请求的时候,是否会实例化。
看每次请求的时候,是否会实例化。
#8
同步你的service方法就可以了
#9
我取了10条数据之后会修改状态.
如:我要查询状态==1的.
等第一个人获取到数据之后我会把状态改成==2
第二个人来查询的时候还是以状态==1来查询.
这样的话应该是没问题的吧.
#10
哦,如果这样是没问题的。
其实如果你把这个过程做为一个完整事务来处理的话,数据库层面都可以控制住相互之间不冲突。
#11
交给事务吧,事务的四个特性保证完成任务。
#12
【完整事务来处理】什么意思啊?
数据库层面都可以控制住相互之间不冲突?
又啥意思啊?还有别的方法嘛?说说呗.
#13
楼主对数据库事务不太熟悉么?
如果是JDBC的话,首先关闭自动提交,然后做Select数据时:
Select Top 10 * From ... For Update
然后对ResultSet进行修改(updateXXOO),最后 commit();
数据库为了保证事务一致性,会把你所选择出来的记录集锁定住(行锁或表锁),这样就控制住并发了。
如果是JDBC的话,首先关闭自动提交,然后做Select数据时:
Select Top 10 * From ... For Update
然后对ResultSet进行修改(updateXXOO),最后 commit();
数据库为了保证事务一致性,会把你所选择出来的记录集锁定住(行锁或表锁),这样就控制住并发了。
#14
我用的Struts2+Spring+Hibernate
#15
这个是可以的.我的框架里面带着事物控制的.如果出错会全部回滚.
我用的hibernate+杭锁就可以了.
#16
http://wangxr66.iteye.com/blog/1469077
我看到这篇文章中最后说道了一句话
"在Struts2与Spring集成时,配置Action的Bean时一定记得加上scope属性,值为:prototype,否则会有线程安全问题。 "
我要是把他设置成单例的话会有线程安全问题吗?
我有点蒙了.
我看到这篇文章中最后说道了一句话
"在Struts2与Spring集成时,配置Action的Bean时一定记得加上scope属性,值为:prototype,否则会有线程安全问题。 "
我要是把他设置成单例的话会有线程安全问题吗?
我有点蒙了.
#17
它说的是Action的“Bean”,如果所有请求都共享一个“Bean”,那不是死定了。。。
#18
晕...下我一跳...我把他的话看成了Action...如果吧Action设置成了prototype的话不就没啥用了嘛...
我在在数据查询和更新的时候增加了hibernate事物,就怕在做更新数据库状态操作的时候出现错误...
不过估计应该不会出错误...
action已经是单例了在加上synchronized
已经可以了
万一出现错误了还有事物可以去控制回滚一下...
这就足够了吧.
#19
可以使用Spring+jms+queue
#20
为什么不能获得同样的数据?
我没看出来你的业务场景,以及可预见的代码中存在线程安全问题
我没看出来你的业务场景,以及可预见的代码中存在线程安全问题
#21
如果获得同样的数据的话多个财务对一条数据做处理的话,首先工作重复了,而且最后如果出错了
也不好找到相应的责任人.
所以要避免数据被同时操作.
#22
理论上是绝对够了的。
不过我补充下:
数据库层面的控制是最合理且安全的,而且基本上就以数据库实现为准。
synchronized的潜在问题是:集群。如果你的部署环境是集群环境,那么synchronized可没法在多个JVM之间保证同步;所以你看到,为啥我说数据库层面控制才是最安全的。
所以,为了避免编码级的疏漏,你要故意做些测试,控制好两个请求同时去操作数据库(比如在Select之后增加Sleep(10000),然后再做其它处理,然后继续Sleep(10000),然后再提交)。
关键性设计和实现必须得到验证,否则从技术人员角度来说,是不严谨的做事方法。
#23
我这里暂时不会集群.
而且我加了hibernate的事物如果出现错误了就直接回滚了,不返回给页面数据了.而是提示他有错误了.
数据库方面实现的话要如何实现呢?我这里用的是mysql
简单提一下吧谢谢
#24
数据库层面控制就是我13楼说的,Select的时候就要加锁。
不过我对Hibernate不太熟悉,没研究过怎么实现选择时加锁。
不过我对Hibernate不太熟悉,没研究过怎么实现选择时加锁。
#25
哦```知道了
我研究一下...看看在数据库层面怎么弄...
谢了...
#26
数据同时操作可以使用乐观锁或者悲观锁就行了,没必要这样进行同步的
#27
我了解一下
回头再开个帖子大家聊聊
这个锁的问题吧.