我的 Java 应用程序需要以原子和隔离的方式执行一组 DB 语句。例如,应用程序需要从一个表中读取数据行并更新另一个表中的数据行。
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 并稍后显式提交来实现的,如上所示。但是上面的代码也可以在多线程环境中执行,我还希望两个数据库语句(选择和更新)作为一个整体相互独占运行。
我有一些想法在该方法中使用共享的 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();
}
它似乎有能力解决这个问题。但是,我想知道这是否是最佳实践,是否有更好的替代方案(例如框架)?