并发入库面临重复数据的问题
以User类为例,当添加一个用户时,首先会去判断用户是否已经存在(即username是否已经在数据库中了),若是没有,则insert一条用户数据,若是有,则提示用户名已存在。数据库
将这个操做看做函数:UserService.saveUser(User user),有3个步骤:安全
private int saveUser(User user) {
if (1.username不存在) { // 2.入库; } else { // 3.提示用户名已存在; }
}
这个saveUser函数其实是线程不安全的,假设两个线程A和线程B,两个线程同时进行了判断(步骤1),发现username不存在,那么就会致使user表中插入了两个username同样的数据(步骤2)。并发
解决方案一分布式
最直接的,经过添加synchronized关键字,将方法变成同步方法。函数
优势:简单直接性能
缺点:性能问题;后期的维护成本较高;最终要的,当服务部署在多台设备时不起做用spa
解决方案二线程
在数据库的user表中,将username字段设为惟一索引,这样当插入重复数据时,数据库会抛出异常,没法入库,能够经过异常处理的方式来处理code
优势:从比较根源的数据库层面解决了问题,适用与分布式环境blog
缺点:须要关注异常处理