Java MySQL 有可能造成死锁吗?
Java MySQL possible to cause a deadlock?
我编写了一个 java 应用程序,其中不同的线程(每个线程都有一个使用连接池 c3p0 的自己的连接对象)调用类似的方法。
伪代码:
void example(Connection connection) {
connection.update("LOCK TABLES Test WRITE");
resultSet = connection.query("SELECT * FROM Test WHERE Id = '5'");
if (resultSet.next()) {
connection.update("UPDATE Test SET Amount = '10' WHERE Id = '5'");
} else {
connection.update("INSERT INTO Test (Id, Amount) VALUES ('5', '10')");
}
connection.update("UNLOCK TABLES");
connection.commit();
}
还有一些其他类似的方法可以锁定 table、select/update/insert 某物然后解锁 table。目的是防止竞争条件和死锁。
从不同的线程调用这样的方法会不会导致MySQL死锁?如果是,您能否举例说明这是如何发生的(导致死锁的两个事务的时间安排)?我是一个有僵局的菜鸟,我想参与其中。
编辑:明确方法中应该使用的连接是从调用方法的线程传递过来的。
编辑:将 READ 替换为 WRITE
这里不行。由于没有复杂的逻辑,并且代码在更新后立即提交,因此必须始终有一个线程经过。即使在更复杂的场景中,它也可能需要最高的序列化级别(可重复读取),我认为 MySql 不支持。
这可能会造成死锁。实际上我不确定它是否会执行,因为你需要获得一个 "WRITE" 锁,而不是 "READ".
我编写了一个 java 应用程序,其中不同的线程(每个线程都有一个使用连接池 c3p0 的自己的连接对象)调用类似的方法。
伪代码:
void example(Connection connection) {
connection.update("LOCK TABLES Test WRITE");
resultSet = connection.query("SELECT * FROM Test WHERE Id = '5'");
if (resultSet.next()) {
connection.update("UPDATE Test SET Amount = '10' WHERE Id = '5'");
} else {
connection.update("INSERT INTO Test (Id, Amount) VALUES ('5', '10')");
}
connection.update("UNLOCK TABLES");
connection.commit();
}
还有一些其他类似的方法可以锁定 table、select/update/insert 某物然后解锁 table。目的是防止竞争条件和死锁。
从不同的线程调用这样的方法会不会导致MySQL死锁?如果是,您能否举例说明这是如何发生的(导致死锁的两个事务的时间安排)?我是一个有僵局的菜鸟,我想参与其中。
编辑:明确方法中应该使用的连接是从调用方法的线程传递过来的。
编辑:将 READ 替换为 WRITE
这里不行。由于没有复杂的逻辑,并且代码在更新后立即提交,因此必须始终有一个线程经过。即使在更复杂的场景中,它也可能需要最高的序列化级别(可重复读取),我认为 MySql 不支持。
这可能会造成死锁。实际上我不确定它是否会执行,因为你需要获得一个 "WRITE" 锁,而不是 "READ".