我特别针对无状态会话Bean问这个问题。我知道我可以使用DataSource
注释轻松注入@Resource
。但我不知道获得Connection
的正确方法是什么。是在bean的每个方法中,还是在用@PostConstruct
注释的方法中?并且关闭Connection
。我是否必须在每个方法调用的finally块中或在使用@PreDestroy
注释的方法中关闭它?
为Connection
创建实例变量是否安全,例如:
@Stateless
public class MyBean {
@Resource private DataSource ds;
private Connection conn;
@PostConstruct
public void onCreate() {
conn = ds.getConnection(); // within try catch block
}
@PreDestroy
public void onDestroy() {
conn.close() // within try catch block
}
}
或者我应该在每个方法中在本地创建它们:
@Stateless
public class MyBean {
@Resource private DataSource ds;
public void method1() {
Connection conn = null;
// get and close connection...
}
public void method2() {
Connection conn = null;
// get and close connection...
}
}
互联网上的一些人这样做,而其他一些人也这样做。在具有高请求流量的应用程序中实施的正确方法是什么?当bean实例返回EJB池时,Connection
是否仍然打开或是否返回到数据库池?
注意:应用程序正在使用本机JDBC API。没有JPA,JDO等。应用服务器是Wildfly。
答案 0 :(得分:2)
TL; DR 第二种方法是正确的方法。只需确保关闭连接以将其返回到池中。
数据源是一个连接池,每次获得连接时它都会从数据源中借用一个连接,当您关闭该连接时,它将返回到池中,因此您总是希望尽快释放连接。
在第一种方法中,只要EJB存在于内存中,您就会保留连接。由于EJB是一个无状态bean,它将长期存在并由不同的消费者重用。使每个EJB至少有一个连接打开,因此这种方法不实用。
第二种方法是正确的方法。只需确保关闭连接以将其返回池。使用这种方法,Bean只会在使用时保留连接。只需确保关闭连接以将其返回到池中。
@Stateless
public class MyBean {
@Resource private DataSource ds;
public void method1() {
try(Connection conn = ds.getConnection()){
// Do anything you need with the connection
}
}
public void method2() {
Connection conn = ds.getConnection();
try {
// Do anything you need with the connection
} finally {
connection.close();
}
}
}