余额问题 http://bibaoke.com/post/24 的处理,还有一种等价方法:
update balance set value = value - 1 where id = 1 and value >= 1
用一个 update 语句表示如果用户余额足够,即扣减余额,数据库会对数据放置排它锁。这样既不会出现余额负数的情况,也不会产生死锁。
相比之前的方案,这个方案更加的简便。
之前的方案则更加的灵活,因为事务的创建和提交一般在 Web 服务器里通过 ODBC 去调用。检查余额是否足够这个查询也可以在多个地方重用,比如在用户使用余额之前,就提醒用户充值。
重复用户问题 http://bibaoke.com/post/26 也有一种等价的处理方法:
insert app_user select '13800002222' where not exists( select * from app_user with(holdlock, updlock) where mobile = '13800002222')
即使使用了子查询,这一个语句还是在一个隐式的事务中,所以 exists 后面的子查询放置的锁,会在整个语句完成之后才释放。
这样写的优点也是脚本较短,缺点也是不如前面的方案灵活,还有就是似乎 MySQL 还不支持这种 insert … select … 的写法,也不支持 holdlock 表提示。