- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在使用 MySQL 的 SELECT .. FOR UPDATE 时遇到问题,这是我尝试运行的查询:
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-1New connection..[OUTPUT FROM SELECT Lock ]...threadName=Thread-2New connection..pst=Thread-2: SELECT * FROM b2biCheckPoint WHERE HostName='UnknownHost' ORDER BY UpdateTimestamp asc limit 1 FOR UPDATEpst=Thread-1: SELECT * FROM b2biCheckPoint WHERE HostName='UnknownHost' ORDER BY UpdateTimestamp asc limit 1 FOR UPDATEoid_oldest/host/threadName==1/UnknownHost/Thread-2oid_oldest/host/threadName==1/UnknownHost/Thread-1[Performing UPDATE] ... oid = 1, thread=Thread-2New connection..[Performing UPDATE] ... oid = 1, thread=Thread-1pst_threadname=Thread-2: UPDATE b2bicheckpoint SET HostName='1_host_Thread-2',UpdateTimestamp=1294940161838 where OID = 1New connection..pst_threadname=Thread-1: UPDATE b2bicheckpoint SET HostName='1_host_Thread-1',UpdateTimestamp=1294940161853 where OID = 1
最佳答案
您非常困惑,但至少经过您的编辑后情况看起来好多了。有多种方法可以做到这一点,但我发现最好的方法是实际使用 JDBC 的 ResultSet.update*
方法:
首先,您需要使用 ResultSet.CONCUR_UPDATABLE
参数准备您的 SELECT ... FOR UPDATE
语句,如下所示:
ps = conn.prepareStatement(query,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
然后,您必须使用 ResultSet 实际更新表:
if(rs.next())
{
rs.updateString(columnIndex, "new_hostname");
rs.updateRow();
}
第三,您可能需要使用事务,我可以在您的更新中看到它。希望您的 DbUtil.close
方法不会抛出任何异常、检查 null 等。此外,如果您的方法变得更复杂,您也应该在其中包含回滚逻辑。
您不应该出于任何原因修改 my.ini
。
关于java - JDBC 使用 SELECT FOR UPDATE 锁定一行,不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4682871/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!