gpt4 book ai didi

Java sql 事务。我究竟做错了什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:04:45 24 4
gpt4 key购买 nike

我编写这个小测试的唯一目的是更好地理解 jdbc 中的事务。虽然我按照文档做了所有的事情,但测试并不希望正常工作。

表结构如下:

CREATE TABLE `default_values` (
`id` INT UNSIGNED NOT auto_increment,
`is_default` BOOL DEFAULT false,
PRIMARY KEY(`id`)
);

测试包含 3 个类:

public class DefaultDeleter implements Runnable
{

public synchronized void deleteDefault() throws SQLException
{
Connection conn = null;
Statement deleteStmt = null;
Statement selectStmt = null;
PreparedStatement updateStmt = null;
ResultSet selectSet = null;

try
{
conn = DriverManager.getConnection("jdbc:mysql://localhost/xtest", "root", "");
conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

// Deleting current default entry
deleteStmt = conn.createStatement();
deleteStmt.executeUpdate("DELETE FROM `default_values` WHERE `is_default` = true");

// Selecting first non default entry
selectStmt = conn.createStatement();
selectSet = selectStmt.executeQuery("SELECT `id` FROM `default_values` ORDER BY `id` LIMIT 1");

if (selectSet.next())
{
int id = selectSet.getInt("id");

// Updating found entry to set it default
updateStmt = conn.prepareStatement("UPDATE `default_values` SET `is_default` = true WHERE `id` = ?");
updateStmt.setInt(1, id);
if (updateStmt.executeUpdate() == 0)
{
System.err.println("Failed to set new default value.");
System.exit(-1);
}
}
else
{
System.err.println("Ooops! I've deleted them all.");
System.exit(-1);
}

conn.commit();
conn.setAutoCommit(true);
}
catch (SQLException e)
{
try { conn.rollback(); } catch (SQLException ex)
{
ex.printStackTrace();
}

throw e;
}
finally
{
try { selectSet.close(); } catch (Exception e) {}
try { deleteStmt.close(); } catch (Exception e) {}
try { selectStmt.close(); } catch (Exception e) {}
try { updateStmt.close(); } catch (Exception e) {}
try { conn.close(); } catch (Exception e) {}
}
}

public void run()
{
while (true)
{
try
{
deleteDefault();
}
catch (SQLException e)
{
e.printStackTrace();
System.exit(-1);
}

try
{
Thread.sleep(20);
}
catch (InterruptedException e) {}
}
}

}

public class DefaultReader implements Runnable
{

public synchronized void readDefault() throws SQLException
{
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;

try
{
conn = DriverManager.getConnection("jdbc:mysql://localhost/xtest", "root", "");

conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

stmt = conn.createStatement();
rset = stmt.executeQuery("SELECT * FROM `default_values` WHERE `is_default` = true");

int count = 0;
while (rset.next()) { count++; }

if (count == 0)
{
System.err.println("Default entry not found. Fail.");
System.exit(-1);
}
else if (count > 1)
{
System.err.println("Count is " + count + "! Wtf?!");
}

conn.commit();
conn.setAutoCommit(true);
}
catch (SQLException e)
{
try { conn.rollback(); } catch (Exception ex)
{
ex.printStackTrace();
}

throw e;
}
finally
{
try { rset.close(); } catch (Exception e) {}
try { stmt.close(); } catch (Exception e) {}
try { conn.close(); } catch (Exception e) {}
}
}

public void run()
{
while (true)
{
try
{
readDefault();
}
catch (SQLException e)
{
e.printStackTrace();
System.exit(-1);
}

try
{
Thread.sleep(20);
}
catch (InterruptedException e) {}
}
}

}

public class Main
{

public static void main(String[] args)
{
try
{
Driver driver = (Driver) Class.forName("com.mysql.jdbc.Driver")
.newInstance();
DriverManager.registerDriver(driver);

Connection conn = null;
try
{
conn = DriverManager.getConnection("jdbc:mysql://localhost/xtest", "root", "");
System.out.println("Is transaction isolation supported by driver? " +
(conn.getMetaData()
.supportsTransactionIsolationLevel(
Connection.TRANSACTION_SERIALIZABLE) ? "yes" : "no"));
}
finally
{
try { conn.close(); } catch (Exception e) {}
}

(new Thread(new DefaultReader())).start();
(new Thread(new DefaultDeleter())).start();

System.in.read();
System.exit(0);
}
catch (Exception e)
{
e.printStackTrace();
}
}

}

我已经编写了脚本,每次运行都会用 100k 条记录(其中一条是默认记录)填充表格。但是每次我运行这个测试时,输出都是:

Is transaction isolation supported by driver? yes

Default entry not found. Fail.

这段代码有什么问题?

最佳答案

请确保您正在创建 InnoDB 表,MyISAM(默认)不支持事务。您可以将您的数据库创建更改为:

CREATE TABLE `default_values` (
`id` INT UNSIGNED NOT auto_increment,
`is_default` BOOL DEFAULT false,
PRIMARY KEY(`id`)
) Engine=InnoDB;

另一个例子:MySQL transaction with accounting application

关于Java sql 事务。我究竟做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1260567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com