分布式锁-mysql行锁
锁工具类 MutexUtil
public class MutexUtil {
public static void lock(String mutexName,Connection connection) {
PreparedStatement preparedStatement= null;//获得锁
ResultSet resultSet = null;
int id=-1;
try {
//不自动提交事物
connection.setAutoCommit(false);
//获取行级锁
preparedStatement = connection.prepareStatement
("select id, mutex_name from mutex where mutex_name = ? for update ");
preparedStatement.setString(1,mutexName);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
id=resultSet.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("获得锁 id="+id);
}
public static void unlock(Connection connection){//关闭锁
try {
//关闭锁 同时提交事物
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
测试类
@Autowired
DataSource dataSource;
void testMapper() throws SQLException {
Connection connection=dataSource.getConnection();
Connection connection2=dataSource.getConnection();
MutexUtil.lock("mutex1",connection);
Runnable run=new Runnable() {
@Override
public void run() {
MutexUtil.lock("mutex1",connection2);
MutexUtil.unlock(connection2);
}
};
//开启其他线程索取锁
Thread thread=new Thread(run);
thread.start();
for(int i=0;i<100000;i++){
System.out.print(i+" ");
}
//while (true);
MutexUtil.unlock(connection);
}
输出
获得锁 id=1
1 2 ... 100000
获得锁 id=1
证明必须要等第一个线程释放锁后,第二个线程才能获取锁
优点:
实现简单
缺点:
1.这把锁没有失效时间,一旦出错,会无法释放锁,其他线程无法再获得到锁
而且排他锁长时间不提交,就会占用数据库连接。一旦类似的连接变得多了,就可能把数据库连接池撑爆
2.锁定之后服务宕机,无法释放?使用这种方式,服务宕机之后数据库会自己把锁释放掉