做个平台间余额的互相转账,重点在于如何解决并发访问数据错乱的问题.比如俩个人之间同时都在给对方转账.以及很多人同时给一个人转账.必须保证数据库里面的数据是随时正确的.
我本没有想到过这一层面,被提醒的.
比如有个转账的方法transfer(业务逻辑主要写在这里)
1.首先想到的用多线程加锁,看了资料.是可以实现,但是问题是对方法加锁或者代码块加锁,那么每次只能执行一个线程,a转给b执行了,可c却不能同时转给d,二者根本不会影响啊.所以多线程白看了.
2.然后就取决在数据库上面了.用的是mysql innodb,所以找了这方面锁的知识.
这篇博客写的不错,感谢:
http://www.cnblogs.com/Arlen/articles/1756616.html
结合其他的参考学习,我总结了一下:
mysql innodb主要有表级锁和行级锁,转账之间不能互相影响,所以选择行级锁.
行级锁有两种:共享锁和排他锁
如何加锁:共享锁:select xxxx lock in share mode
排他锁:select xxx for update
顾名思义共享锁的重点在于多个事务可以同时共享同一资源上的共享锁,如果一个事务获取了一个数据的共享锁,那么别的事务也可以再获取这个锁.获取共享锁的事务可以对数据进行读操作.,读完了就释放.
排他锁就是一旦事务获取了这个锁,他就必须持有这个锁到结束,并不准其他事务获取这个锁.持有排他锁的事务可以对数据进行写操作.
然后明确一点一个事务在一个时刻里只能拥有一把锁
在转账时如果我先查找用户的账户信息,如果我用共享锁的话,别的事务也可以共享这个锁,这时候就会产生死锁.
这里的死锁产生的原因在于:
当A向B转账的时候,B也在向C转账,A开始转账的时候获取A,B账户信息,A开始转账的时候获取C,B账户信息,这里是共享锁,然后我需要对账户进行更新,这时候问题就出现了;
假如A转账在准备更新B的信息时,发现B转账也准备更新B,A就等B释放共享锁,B也等A在释放共享锁,也就产生死锁了.