0 0

MyBatis事务并发控制锁定问题-很心焦0

我们系统采用springMVC+MyBatis的架构,数据使用的是mysql,数据库的隔离级别是默认的:REPEATABLE-READ。现在发现一个事务并发控制锁定问题。
我们系统有一个业务逻辑,每个人只能执行一次,所以开启事务的时候,我们使用悲观锁进行控制:select * from table where type = 1 and id = XXX for update;如果用户点击非常快,点击两次的话,就会启动两个事务进行控制,暂定A和B两个事务。假如A事务先获得锁,那么只有A事务执行完成之后B事务才能获得锁,B事务就会处于等待状态。A事务在处理完成之后,就会把类型type修改了,改成了其他的值,比如说:2,但是B事务在获得了锁之后,即本语句select * from table where type = 1 and id = XXX for update;能够执行通过,但是该用户的type还是1,即还是A事务修改之前的数值。
请各位大牛多多帮忙!!!
小弟感激不尽!!!
2014年11月03日 17:16

8个答案 按时间排序 按投票排序

0 0

如果用户点击非常快,点击两次的话,就会启动两个事务进行控制

可以在页面添加一个防止多次提交的功能。就不会出现两个事物的问题了

2017年3月20日 17:16
0 0

而且也不执楼主这样使用mysql的悲观锁。悲观锁在没有走索引的情况下会变成表级锁。

2014年11月07日 15:38
0 0

修改你的SQL:去除查询条件type = 1 。事务A获取锁后,在代码中过虑出需要更新的记录,然后更新记录,提交事务。此时事务B就可以获取锁,查询出需要更新的最新记录(被事务A更新后的记录),再在代码中过虑需要更新的记录(逻辑同事务A),及可解决你的问题。

2014年11月07日 14:31
0 0

select * from table where type in ( select type from table where id =xxx ) and id = XXX for update;

2014年11月05日 15:33
0 0

另起一张表用每个人的标识做主键。插入表数据作为一个事务。如果那个人已经做过就插入不了。事务里面你想要只执行一次也回回滚。

2014年11月04日 17:27
0 0

考虑以下做法:
1)考虑将事务的隔离级别修改为read-commited;
2)事务B应该后续会做一定的更新的,可以在更新后面加一个type条件,比如说update table set xxxx where id=xxx and type=xxx,避免重复更新。根据返回结果的数量(如果是0的话表示已经被其他人更新过了)决定程序如何处理(放弃或者重试)

2014年11月04日 08:01
0 0

java 代码级锁呢, 事物的代码加同步锁

2014年11月03日 18:42
0 0

幻影读,必须加range锁。
比如你应该用
select * from table where id = XXX for update;
去悲观锁一片数据
获得锁之后(另一个事务提交后)
select * from table where type = 1 and id = XXX for update;
就可以取得正确的数据了。

2014年11月03日 17:48

相关推荐

Global site tag (gtag.js) - Google Analytics