一、背景
在P2P项目中,活期通过一张主表t_bid_transfer_control记录用户的总金额,t_bid_order表记录用户取出和存入活期宝的记录。
示例:
t_bid_transfer_control表:
member_id 100
t_bid_order表:
member_id 10 TRANSFER_SUCCESS (转出)
member_id 5 CURRENT_SUCCESS (存入)
活期转出过程:查询主表余额是否足够,足够则记录明细表一条TRANSFER_SUCCESS转出记录。然后调用tss即时转账服务从公司活期专户转出金额到用户账户上。最后更新余额表记录。
如下图:
二、方案一
1、使用synchronized同步方法或者synchronized同步代码块解决。
2、使用JDK1.5后的原子锁Lock解决。
分布式部署,示例如下:
三、方案二
1、 使用数据库行数 select 余额 for update
2、使用分布式锁redis或者zk等解决 。 setnx key value timeout
3、事务提交后释放锁,此时余额已经被更新,第二个线程拿到锁后,首先进行查询,查询到的是更新后的余额。 100——>80
如下图:
四、代码讲解
1、活期宝代码
五、常用锁
悲观锁:查询数据时,先锁定不可修改,当事务提交后释放锁。同时只有一个线程能操作数据。
乐观锁:不锁定修改数据,在最后修改值时通过版本比较(CAS原理)。
锁的重入:锁的嵌套调用
悲观锁:行数、表数 select ….for update
乐观锁:oracle底层update操作是通过SCN(检查点、积累数字),oracle的操作=select+update