XA Transaction propagation within many threads

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

XA Transaction propagation within many threads

Drew Kutcharian
Hi Everyone,

How can I use Bitronix in the following use case:

Let's assume we have the following class:

public class Dao {
    public void updateDatabase(DB db) {
        connet to db
        run a sql
    }
}

and we create a Java Runnable from that, like the following:

public class MyRunnable extends Runnable {

    Dao dao;
    DB db;

    public MyRunnable(Dao dao, DB db) {
        this.dao=dao;
        this.db = db;
    }            

    public run() throws Exception {
        return dao.updateDatabase(db);
    }
}

Now in our Service layer, we have another class:

public class Service {
    public void updateDatabases() {
        BEGIN TRANSACTION;
   
        ExecutorService es = Executors.newFixedThreadPool(10);
        ExecutorCompletionService ecs = new ExecutorCompletionService(es);
        List<Future<T>> futures = new ArrayList<Future<T>>(n);
        Dao dao = new Dao();
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db1")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db2")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db3")));

        for (int i = 0; i < n; ++i) {
    completionService.take().get();
        }

       END TRANSACTION;
    }

}

And the client can be a Servlet or any other multi-threaded environment:

public MyServlet extend HttpServlet {
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        Service service = new Service();
        service.updateDatabases();
    }
}

What would be the correct code for BEGIN TRANSACTION and END TRANSACTION parts? Is this even feasible? If not, what needs to be changed? The requirements is to keep the updateDatabases() method concurrent (since it will be accessing multiple databases at the same time) and transactional.

Thanks,

Drew





Reply | Threaded
Open this post in threaded view
|

Re: XA Transaction propagation within many threads

Ludovic Orban-2
Hi,

You cannot do that, JTA mandates that a transaction must be bound to a single thread. Unfortunately, I can't think of an alternate way of doing what you described and as far as I know all transaction managers I've ever seen out there can't do that.

Sorry,
Ludovic


2011/3/11 Drew Kutcharian <[hidden email]>
Hi Everyone,

How can I use Bitronix in the following use case:

Let's assume we have the following class:

public class Dao {
    public void updateDatabase(DB db) {
        connet to db
        run a sql
    }
}

and we create a Java Runnable from that, like the following:

public class MyRunnable extends Runnable {

    Dao dao;
    DB db;

    public MyRunnable(Dao dao, DB db) {
        this.dao=dao;
        this.db = db;
    }            

    public run() throws Exception {
        return dao.updateDatabase(db);
    }
}

Now in our Service layer, we have another class:

public class Service {
    public void updateDatabases() {
        BEGIN TRANSACTION;
   
        ExecutorService es = Executors.newFixedThreadPool(10);
        ExecutorCompletionService ecs = new ExecutorCompletionService(es);
        List<Future<T>> futures = new ArrayList<Future<T>>(n);
        Dao dao = new Dao();
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db1")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db2")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db3")));

        for (int i = 0; i < n; ++i) {
    completionService.take().get();
        }

       END TRANSACTION;
    }

}

And the client can be a Servlet or any other multi-threaded environment:

public MyServlet extend HttpServlet {
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        Service service = new Service();
        service.updateDatabases();
    }
}

What would be the correct code for BEGIN TRANSACTION and END TRANSACTION parts? Is this even feasible? If not, what needs to be changed? The requirements is to keep the updateDatabases() method concurrent (since it will be accessing multiple databases at the same time) and transactional.

Thanks,

Drew






Reply | Threaded
Open this post in threaded view
|

Re: XA Transaction propagation within many threads

Drew Kutcharian
Yea, I found out that JTA can't really do it, but Atomikos can using SubTxThread class.

- Drew


On Mar 18, 2011, at 5:56 AM, Ludovic Orban wrote:

Hi,

You cannot do that, JTA mandates that a transaction must be bound to a single thread. Unfortunately, I can't think of an alternate way of doing what you described and as far as I know all transaction managers I've ever seen out there can't do that.

Sorry,
Ludovic


2011/3/11 Drew Kutcharian <[hidden email]>
Hi Everyone,

How can I use Bitronix in the following use case:

Let's assume we have the following class:

public class Dao {
    public void updateDatabase(DB db) {
        connet to db
        run a sql
    }
}

and we create a Java Runnable from that, like the following:

public class MyRunnable extends Runnable {

    Dao dao;
    DB db;

    public MyRunnable(Dao dao, DB db) {
        this.dao=dao;
        this.db = db;
    }            

    public run() throws Exception {
        return dao.updateDatabase(db);
    }
}

Now in our Service layer, we have another class:

public class Service {
    public void updateDatabases() {
        BEGIN TRANSACTION;
   
        ExecutorService es = Executors.newFixedThreadPool(10);
        ExecutorCompletionService ecs = new ExecutorCompletionService(es);
        List<Future<T>> futures = new ArrayList<Future<T>>(n);
        Dao dao = new Dao();
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db1")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db2")));
        futures.add(ecs.submit(new MyRunnable(dao, new DB("db3")));

        for (int i = 0; i < n; ++i) {
    completionService.take().get();
        }

       END TRANSACTION;
    }

}

And the client can be a Servlet or any other multi-threaded environment:

public MyServlet extend HttpServlet {
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        Service service = new Service();
        service.updateDatabases();
    }
}

What would be the correct code for BEGIN TRANSACTION and END TRANSACTION parts? Is this even feasible? If not, what needs to be changed? The requirements is to keep the updateDatabases() method concurrent (since it will be accessing multiple databases at the same time) and transactional.

Thanks,

Drew







Reply | Threaded
Open this post in threaded view
|

Re: XA Transaction propagation within many threads

Ludovic Orban-2
True, this can be done with nested transactions which Atomikos supports but not BTM.

Thanks for reminding me this fact!


2011/3/18 Drew Kutcharian <[hidden email]>
Yea, I found out that JTA can't really do it, but Atomikos can using SubTxThread class.

- Drew