У меня проблемы с SELECT в MySQL. ДЛЯ ОБНОВЛЕНИЯ, вот запрос, который я пытаюсь выполнить:
SELECT * FROM tableName WHERE HostName='UnknownHost'
ORDER BY UpdateTimestamp asc limit 1 FOR UPDATE
После этого соответствующий поток выполнит ОБНОВЛЕНИЕ и изменит имя хоста, после чего должен разблокировать строку.
Я запускаю многопоточное Java-приложение, поэтому 3 потока выполняют этот оператор SQL, но когда поток 1 выполняет его, он не блокирует свои результаты из потоков 2 и 3. Поэтому потоки 2 и 3 получают те же результаты, и они могут обновить ту же строку.
Также каждый поток подключен к MySQL.
Я использую Innodb, с транзакцией-изоляцией = READ-COMMITTED, и автокоммит выключен перед выполнением выбора для обновления
могу я что-то пропустить? ИЛИ, может быть, есть лучшее решение?
Большое спасибо.
Код:
public BasicJDBCDemo()
{
Le_Thread newThread1=new Le_Thread();
Le_Thread newThread2=new Le_Thread();
newThread1.start();
newThread2.start();
}
Тема:
class Le_Thread extends Thread
{
public void run()
{
tring name = Thread.currentThread().getName();
System.out.println( name+": Debut.");
long oid=Util.doSelectLockTest(name);
Util.doUpdateTest(oid,name);
}
}
Выберите:
public static long doSelectLockTest(String threadName)
{
System.out.println("[OUTPUT FROM SELECT Lock ]...threadName="+threadName);
PreparedStatement pst = null;
ResultSet rs=null;
Connection conn=null;
long oid=0;
try
{
String query = "SELECT * FROM table WHERE Host=?
ORDER BY Timestamp asc limit 1 FOR UPDATE";
conn=getNewConnection();
pst = conn.prepareStatement(query);
pst.setString(1, DbProperties.UnknownHost);
System.out.println("pst="+threadName+"__"+pst);
rs = pst.executeQuery();
if (rs.first())
{
String s = rs.getString("HostName");
oid = rs.getLong("OID");
System.out.println("oid_oldest/host/threadName=="+oid+"/"+s+"/"+threadName);
}
}
catch (SQLException ex)
{
ex.printStackTrace();
}
finally
{
DBUtil.close(pst);
DBUtil.close(rs);
DBUtil.close(conn);
}
return oid;
}
Пожалуйста, помогите ....:
Результат:
Thread-1: Debut.
Thread-2: Debut.
[OUTPUT FROM SELECT Lock ]...threadName=Thread-1
New connection..
[OUTPUT FROM SELECT Lock ]...threadName=Thread-2
New connection..
pst=Thread-2: SELECT * FROM b2biCheckPoint WHERE HostName='UnknownHost' ORDER BY UpdateTimestamp asc limit 1 FOR UPDATE
pst=Thread-1: SELECT * FROM b2biCheckPoint WHERE HostName='UnknownHost' ORDER BY UpdateTimestamp asc limit 1 FOR UPDATE
oid_oldest/host/threadName==1/UnknownHost/Thread-2
oid_oldest/host/threadName==1/UnknownHost/Thread-1
[Performing UPDATE] ... oid = 1, thread=Thread-2
New connection..
[Performing UPDATE] ... oid = 1, thread=Thread-1
pst_threadname=Thread-2: UPDATE b2bicheckpoint SET HostName='1_host_Thread-2',UpdateTimestamp=1294940161838 where OID = 1
New connection..
pst_threadname=Thread-1: UPDATE b2bicheckpoint SET HostName='1_host_Thread-1',UpdateTimestamp=1294940161853 where OID = 1