【发布时间】:2014-05-21 14:26:34
【问题描述】:
我的 Web 应用程序存在一些并发问题,其中已完成对数据库的写入,并且可能还会同时进行读取。写入首先删除所有行,然后插入新行,因此可能会在数据库为空时完成读取,从而导致错误。我正在使用 ReentrantReadWriteLock,但想确保我正确使用它。任何修复将不胜感激。
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public static Schedule lookupSchedule()
{
lock.readLock().lock();
try
{
// read data from the database, manipulate it, return it
}
finally
{
lock.readLock().unlock();
}
}
public static void setSchedule()
{
Connection conn = DB.getConnection();
lock.writeLock.lock();
try
{
conn.openTransaction();
// delete all the rows from the table
// insert all the new rows into the table
conn.committTransaction();
}
catch (Exception ex)
{
conn.rollbackTransaction();
}
finally
{
lock.writeLock.unlock();
}
}
【问题讨论】:
-
这对我来说很合适。你如何回收你的连接?
-
连接在 commitTransaction() 或 rollbackTransaction() 方法中关闭,并且来自数据库池。
-
您可能希望将数据库连接移到写入锁中,因为看起来您已经为查找方法设置了这种方式。否则你可以让
lookupSchedule()获得一个读锁,然后在它获得数据库连接之前,一堆写者可能会抓住所有的数据库连接然后阻塞写锁,从而导致死锁。 -
你为什么还要使用锁?数据库的 ACID 属性应确保读取器在写入器事务之前使用数据库中的任何数据,即使写入器正在工作......
-
另外,请参阅:stackoverflow.com/questions/11043712/… 理论上您可能会看到幻读行为...您可能只需要调整隔离级别。
标签: java concurrency java.util.concurrent reentrantreadwritelock