【发布时间】:2012-06-09 19:23:14
【问题描述】:
我希望 JdbcPersistenceManager 始终只有一个 jdbcConnection 并通过以下方式对其进行实例化:JdbcConnectionManager.getJdbcConnection()
这是一个简单的模式,摘自 (2004-11-01 | Head First Design Patterns | O'Reilly Media | 688p | by Elisabeth Freeman | ISBN-0596007124),可能被误用、误解和不合适。
是否应该在“this”或专门用于跟踪锁的特定新(静态?)字段上进行同步()锁定?我该怎么做?
public class JdbcPersistenceManager implements PersistenceManager {
private volatile Connection jdbcConnection;
/* ... */
private Connection getJdbcConnection() throws JdbcConnectionFailureException {
if (jdbcConnection == null) {
synchronized (this) {
if (jdbcConnection == null) {
jdbcConnection =
JdbcConnectionManager.getJdbcConnection(jdbcConnectionParameters);
}
}
}
// label:here
return jdbcConnection;
}
}
假设 jdbcConnection 的实例化,即使我们想要标记为“label:here”的点,只是为了论证,如何最好地检查连接是否仍然有效,如果不是则重新创建它?
ConnectionPooling 不是我想在这里做的。只有一个连接...如果它是“null”或“invalid”,则重新生成/重新打开它。
编辑:
我希望 getJdbcConnection 做的是:
1) 提供 jdbcConnections,确保在任何给定时间只存在其中一个(不应允许客户端保留对 2 个不同连接的引用)
和
2) 重新生成(即重新调用 JdbcConnectionManager.getJdbcConnection())“private volatile Connection jdbcConnection”字段,如果由于某种原因它被关闭了
(例如,客户端 1 出现,获得连接但 关闭,客户端 2 出现,连接 not null 但无法使用,因此她得到一个再生的)。
注意:我意识到没有什么可以阻止客户端 1 获得连接,而客户端 2 获得相同的连接,就像设计上一样,并且在客户端 1 通过他的参考关闭它后仅一毫秒使用它...我不知道如果这完全可以解决?
【问题讨论】:
-
您可以为每个客户端创建一个包装器/代理
Connection实例,它们都包装相同的真实Connection并且不传播close()方法,但如果它已关闭,则设置内部真实Connection到null/invalid 并在尝试进一步使用时抛出异常。 -
拥有一个包装类似乎是个好主意......“每个问题都可以通过添加另一个间接级别来解决”,实际报价如何?你提出问题的建议破坏了我想要的再生能力……不是吗?
-
我希望每个客户端都这样,所以如果客户端调用
close(),任何后续操作都会抛出异常,就像真正的连接一样,但这只是一个细节。
标签: java multithreading locking singleton synchronized