0 Replies Latest reply on Dec 31, 2009 11:39 AM by dominus

    Using Interceptor to create transaction management for ODB

    dominus
      Hi,

      I would like to use in my project object database (neodatis), and I would like to have a very simple transaction management mechanism - I can't use any of seam transaction management features. This application should also work in Tomcat/Jetty environment. So I thought about using interceptors to create connection to database and to close it after a method returns.

      It looks like this at the moment:

      public class TransactionInterceptor implements Serializable {
          private static final String ODB_OBJECT_NAME = "odb";
          private static final String ODB_SERVER_NAME = "odbServer";

          @AroundInvoke
          public Object transaction(InvocationContext invocation) throws Exception {

              DBAccess dbAccess = (DBAccess) Contexts.getApplicationContext().get(ODB_SERVER_NAME);
              ODB odb = dbAccess.getOdb();

              Contexts.getEventContext().set(ODB_OBJECT_NAME, odb);
              Object result = null;
              try {
                  result = invocation.proceed();
                  closeOdbConn(odb);
              } catch (Exception e) {
                  odb.rollback();
                  throw new RuntimeException(e);
              } finally {
                  closeOdbConn(odb);
              }

              Contexts.getEventContext().remove(ODB_OBJECT_NAME);
              return result;
          }

          private void closeOdbConn(ODB odb) {
              if (isNotNullAndIsNotClosed(odb)) {
                  odb.close();
              }
          }

          private boolean isNotNullAndIsNotClosed(ODB odb) {
              return odb != null && !odb.isClosed();
          }
      }


      And I have defined this annotation:

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.METHOD, ElementType.TYPE})
      @Interceptors(TransactionInterceptor.class)
      @Documented
      @Inherited
      public @interface ODBTransaction {
      }

      And I use it like this:



      @Name("userRepository")
      public class UserRepositoryImpl {

          @In
          ODB odb;
         
           ....
      }

      @Name("userFacade")
      @ODBTransaction
      public class UserFacadeImpl implements UserFacade {

          @In(create=true)
          UserRepository userRepository;

          // here goes methods that use userRepository
      }



      I would like to ask you if it is ok to use it that way. Is putting odb connection to event context and after that removing it from this context ok?
      Can I use this solution with other scopes?
      Maybe I will get some performance problems with this solution?
      And what's the most important: is it proper solution?

      Of course I could also create odb connection in my business methods and just passing them from services to repositories but I wouldn't like to polute my interfaces.


      Best regards
      Marek Dominiak