Hi,
Hibernate 3 do not use the ?Thread Local? semantic, but uses a transaction listener to
close the connection. I have created some code to behave like Hibernate.
The code has the follow semantic:
1) The client call a EJB method ?doThing? that have required transaction
2) The method ?doThing? gets a connection to the database and register a transaction
listener that will close the connection
3) The method ?doThing? call another EJB method ?doOtherThinkOnDiferentTransacton? that
have requires new transaction
4) The method ?doOtherThinkOnDiferentTransacton? gets a new connection to the database and
register a transaction listener that will close the connection
When the method ?doOtherThinkOnDiferentTransacton? is over, the container invokes the
transactions listeners and then the exception ?Trying to return an unknown connection2? is
written to the log. If the step 2) is not done, the exception does not appear in the log.
Here is the code:
public class Connection2BugBean implements SessionBean {
public Connection2BugBean() {
// Empty
}
public void ejbCreate() throws CreateException {
// Empty
}
public void setSessionContext(SessionContext sessionContext) throws EJBException {
// Empty
}
public void ejbRemove() throws EJBException {
// Empty
}
public void ejbActivate() throws EJBException {
// Empty
}
public void ejbPassivate() throws EJBException {
// Empty
}
public void doThing() {
MyConnectionManager.getConnection();
try {
Context context = new InitialContext();
Connection2BugHome home = (Connection2BugHome)
PortableRemoteObject.narrow(context.lookup("ejb/Connection2Bug"),
Connection2BugHome.class);
Connection2Bug object = home.create();
object.doOtherThinkOnDiferentTransacton();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public void doOtherThinkOnDiferentTransacton() {
MyConnectionManager.getConnection();
}
}
class MyConnectionManager implements Synchronization {
private static final Hashtable CONNECTIONS_BY_TRANSACTIONS = new Hashtable();
private static final Logger log = Logger.getLogger(Connection2BugBean.class);
private Transaction t;
public MyConnectionManager(Transaction t) {
this.t = t;
}
public static Connection getConnection() {
try {
Context context = new InitialContext();
TransactionManager tm = (TransactionManager)
context.lookup("java:/TransactionManager");
Transaction t = tm.getTransaction();
Connection conn = (Connection) CONNECTIONS_BY_TRANSACTIONS.get(t);
if (conn == null) {
log.warn("Creating a connection binded to " + t);
DataSource ds = (DataSource) context.lookup("java:/DefaultDS");
conn = ds.getConnection();
CONNECTIONS_BY_TRANSACTIONS.put(t, conn);
t.registerSynchronization(new MyConnectionManager(t));
}
return conn;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public void beforeCompletion() {
Connection conn = (Connection) CONNECTIONS_BY_TRANSACTIONS.remove(t);
if (conn != null) {
log.warn("Closing the connection binded to " + t);
try {
conn.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
public void afterCompletion(int i) {
}
}
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3960469#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...