Mybatis 如何使用 Mysql 悲观锁,求解答?

被占用 发布于 2015/01/20 10:36
阅读 12K+
收藏 1

项目框架使用的是:Mybatis + Spring +SpringMVC ,数据库是:Mysql

之前遇到一个问题就是,俩用户同时修改同一条数据,结果数据给弄乱了,目前使用的乐观锁来控制的。

公司想用悲观锁来处理试试看,

在网上找了一些资料:

基本上都是设置Mysql 的提交模式为手动 set autocommit = 0 

然后在select  语句后面加上 for update 的方式。

这个方式,我在mysql 的命令行中使用的时候,能够吧数据锁定。

然后在项目中来查询的时候这一条数据就查询不到了,这说明数据已经能够安全锁定了。

但是,有还有2个问题;

问题1:我关闭命令行窗口,重新打开,或者重开一个命令行窗口,还是需要重新设置一下 mysql 的提交模式为手动  set autocommit = 0 

问题2:我在程序中先 set autocommit = 0 然后在 select * from t_user where id = '1' for update,这样执行之后,我在数据库的命令行中在来查询,还是能查询到这条数据。而且,我在次执行这个方法的时候,同样能查询出来,这说明我并没有吧数据锁住。

请问各位,有这方面的思路吗?在线等。

加载中
0
被占用
被占用

引用来自“ZeroOne”的评论

有个问题不解, 

就算你用悲观锁锁住数据应该一直都可以查询得到, 

只不过你不能修改它.你第一次查不到我觉得可能是出了别的问题.

是么?我看到一些博客里面说,锁定之后这条数据查询不到哟~~,请问悲观锁是个怎么回事呀?
shuaixianbo
shuaixianbo
回复 @被占用 : 搜索“mysql mvcc”
被占用
被占用
回复 @ZeroOne : O(∩_∩)O哈哈~,好的哈,谢谢你。我也明白了一些东西,,
甘薯
甘薯
回复 @2B的It青年 : 这个么... 嘿嘿,说多了可能你也不会明白, 和mysql的锁机制有关系. 总之是相当不靠谱的.我对mysql没啥好感, 能讨论的也只有这么多了.
被占用
被占用
回复 @ZeroOne : 道理是这样哈,领导安排的还是要完成它哈,而且对于我自己来说,能搞定悲观锁,也算是多掌握了一项技能哈,所有,还是需要去做的,至于公司用什么,我就不能做主了,不过,你这样说的也有道理,我有点不明白的地方就是,为啥其他数据库的悲观锁安全,反正mysql的乐观锁比悲观锁安全呢?
甘薯
甘薯
回复 @2B的It青年 : 你领导看来水平一般般, 对于其他数据库来说悲观锁可能是比较可靠的,但是mysql不然... 如果从安全角度出发, 乐观锁更安全,因为比较字段如果被人提前修改了那么就必定失败不会被脏数据覆盖.
下一页
1
limeng32
limeng32

引用来自“2B的It青年”的评论

假如我下一个订单,这个时候,订单的状态为1:表示已下单,未发货,这个时候有2个业务员操作后台,a,b  ,a发现这个订单没有发货,在此时,数据已经查询出来了,然后a去泡了一杯咖啡,b呢,在a去泡咖啡的时候,也查询出这个订单,发现未发货,便通知发货,同时修改为2:表示已通知物流发货,物流看见有发货通知,便发货,同时修改数据状态为3:表示已发货。此时,a泡咖啡回来,点击之前已经查询出来的数据,进行发货。修改订单状态为2。目前就是这个样子的。本来这个订单已经为3了,但是a回来还是显示为1,修改为2.这样不就照成了数据错误的问题吗?

@南湖船老大

@南湖船老大 你好,想跟你请教个问题:

 

你这个需求需要使用事务来解决,然而我看了半天都没见你提到。
具体到你的需求来说,应该是这样:你需要开发一个操作,当执行它时,如果目标字段为1则修改为3,如果不为1则不作任何操作,这么理解没错吧?
如果以上正确,那么你需要至少执行两次数据库操作,第一次查询目标字段的值,第二次是更新目标字段的值。你可以把这两次操作放到一个事务中,用悲观锁或者乐观锁来保证事务安全。切记的是,你需要把它们放在事务中由程序来执行,而不是手动执行一部分后喝杯咖啡再执行另一部分。
limeng32
limeng32
回复 @zw6234336 : 事务加上乐观锁,可以保证这件商品只能被卖出一次
zw6234336
zw6234336
事物只是保证了查询 和更新的 一致性,并没有确保 这个查询更新的原子性。如果并发操作同样会出现 一个物品被卖两次的情况
被占用
被占用
你好,非常感谢回答。你所说的不错。当时只是 为了研究 悲观锁的问题。
0
甘薯
甘薯

有个问题不解, 

就算你用悲观锁锁住数据应该一直都可以查询得到, 

只不过你不能修改它.你第一次查不到我觉得可能是出了别的问题.

0
被占用
被占用

假如我下一个订单,这个时候,订单的状态为1:表示已下单,未发货,这个时候有2个业务员操作后台,a,b  ,a发现这个订单没有发货,在此时,数据已经查询出来了,然后a去泡了一杯咖啡,b呢,在a去泡咖啡的时候,也查询出这个订单,发现未发货,便通知发货,同时修改为2:表示已通知物流发货,物流看见有发货通知,便发货,同时修改数据状态为3:表示已发货。此时,a泡咖啡回来,点击之前已经查询出来的数据,进行发货。修改订单状态为2。目前就是这个样子的。本来这个订单已经为3了,但是a回来还是显示为1,修改为2.这样不就照成了数据错误的问题吗?

@南湖船老大

@南湖船老大 你好,想跟你请教个问题:

 

被占用
被占用
回复 @學無止境 : 是滴呢,其实 对于技术还说解决方法很多,能弄明白为什么就更好了,
學無止境
學無止境
回复 @2B的It青年 : 其实大家都一样,都是从傻逼到逗比,然后慢慢进化到牛逼,什么问题都有很多解决方案,就看自己想不想用心的去解决。
被占用
被占用
回复 @學無止境 : 你好 ,谢谢。什么都是从无到有,团队不扎地也许是真的,感谢回答。
學無止境
學無止境
这中问题都能出现只能说明你们团队不咋地。难道修改之前就不能先判断一下?
返回顶部
顶部