gpt4 book ai didi

java - Java中锁定一组DB操作

转载 作者:行者123 更新时间:2023-12-02 08:36:35 25 4
gpt4 key购买 nike

我的 Java 应用程序需要以原子和隔离的方式执行一组数据库语句。例如,应用程序需要从一个表中读取数据行并更新另一表中的数据行。

QueryRunner queryRunner = new QueryRunner(); // DBUtils query runner

Object[] params = new Object[] { param };

Connection conn = null;
try {
conn = ...; // get connection
conn.setAutoCommit(false);
result = queryRunner.query(conn, "select x, y, z from table1 where column1 = ?", new BeanHandler<SomeBean>(SomeBean.class), params);

// logic to get value for update

queryRunner.update(conn, "update table2 set p = ? where q = ?", some_value, some_id);
conn.commit();
} catch (SQLException e) {
//
} finally {
DBUtils.closeQuietly(conn);
}

事务管理是通过将连接的自动提交设置为 false 并稍后显式提交来实现的,如上所示。但上面的代码也可以在多线程环境中执行,并且我还希望两个 DB 语句(select 和 update)作为一个整体互斥地运行。

我有一些在该方法中使用共享 Java Lock 对象的想法,如下所示。

在类里面,

private Lock lock = new ReentrantLock(); // member variable

在方法中,

lock.lock();
try {
conn = ...; // get connection
conn.setAutoCommit(false);

result = queryRunner.query(conn, "select x, y, z from table1 where column1 = ?", new BeanHandler<SomeBean>(SomeBean.class), params);

// logic to get value for update

queryRunner.update(conn, "update table2 set p = ? where q = ?", some_value, some_id);
conn.commit();
} finally {
DBUtils.closeQuietly(conn);
lock.unlock();
}

似乎能够解决这个问题。但是,我想知道这是否是最佳实践,是否有更好的替代方案(例如框架)?

最佳答案

我的建议是让数据库为您而不是您的应用程序管理这些锁。这可以处理有多个 JVM 运行代码的情况。您提到的锁定机制只能在单个 JVM 中有效。

实现此目的的方法是执行SELECT ... FOR UPDATE。这将在选定的行上放置一个锁,并且当提交或回滚事务时该锁将被释放。这比表级锁更好,因为这些行仍然可以被只想读取当前值但不想更新它们的其他事务读取。如果另一个事务尝试获取 FOR UPDATE 锁,那么它将阻塞,直到第一个事务完成。

关于java - Java中锁定一组DB操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10015125/

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