一、模拟问题:同一个用户连续点击保存按钮,造成保存重复问题。(第二次请求,查询时,第一次还没有保存到数据库)
@Transactional
public class TestUserImpl implements TestUserService {
public void saveUserAll(int userId) {
//1、判断是否已经存在
boolean result = this.getUser(userId);
try {
Thread.sleep(15000);
} catch (Exception e) {
e.printStackTrace();
}
//2、不存在,保存
if (result) {this.saveUser(userId);}else{System.out.println("用户已经存在userId="+userId);}
}
@Transactional(isolation = Isolation.SERIALIZABLE)
public void saveUser(int userId) {
System.out.println("开始保存----userId="+userId);
User user= new User();
user.setUserId(userId);
userDao.save(user);
System.out.println("完成保存----userId="+userId);
}
public boolean getUser(int userId) {
System.out.println("查询----userId="+userId);
String sql = "SELECT id from user where userId="+userId+"";
List list = userDao.findBysql(sql);
if (list.size() > 0) {
return false;
} else {
return true;
}
}
}
------------------------输出结果------------------------------
查询----userId=1
查询----userId=1
开始保存----userId=1
完成保存----userId=1
开始保存----userId=1
完成保存----userId=1
---------------------解决办法:在saveUserAll方法上加锁synchronized----------------------
public synchronized void saveUserAll(int userId)
-----------------------------------------------------------------------------------------------------------------------
二、在saveUserAll上加SERIALIZABLE,同意用户连续点击或不同用户并发请求时,造成死锁
@Transactional
public class TestUserImpl implements TestUserService {
@Transactional(isolation = Isolation.SERIALIZABLE)
public void saveUserAll(int userId) {
//1、判断是否已经存在
boolean result = this.getUser(userId);
try {
Thread.sleep(15000);
} catch (Exception e) {
e.printStackTrace();
}
//2、不存在,保存
if (result) {this.saveUser(userId);}else{System.out.println("用户已经存在userId="+userId);}
}
public void saveUser(int userId) {
System.out.println("开始保存----userId="+userId);
User user= new User();
user.setUserId(userId);
userDao.save(user);
System.out.println("完成保存----userId="+userId);
}
public boolean getUser(int userId) {
System.out.println("查询----userId="+userId);
String sql = "SELECT id from user where userId="+userId+"";
List list = userDao.findBysql(sql);
if (list.size() > 0) {
return false;
} else {
return true;
}
}
}
------------------------输出结果----------------------------------------------------------------------
查询----userId=1
查询----userId=2
开始保存----userId=1
开始保存----userId=2
成功保存----userId=1
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
----------------------------------------------------------------------------------------------------------------------