views:

341

answers:

3

Preliminary:

I have an application which maintains a thread pool of about 100 threads. Each thread can last about 1-30 seconds before a new task replaces it. When a thread ends, that thread will almost always will result in inserting 1-3 records into a table, this table is used by all of the threads. Right now, no transactional support exists, but I am trying to add that now. Also, the table in question is InnoDB. So...

Goal

I want to implement a transaction for this. The rules for whether or not this transaction commits or rollback reside in the main thread. Basically there is a simple function that will return a boolean.

  1. Can I implement a transaction across multiple connections?
  2. If not, can multiple threads share the same connection? (Note: there are a LOT of inserts going on here, and that is a requirement).
+1  A: 

1) No, a transaction is limited to a single DB connection.

2) Yes, a connection (and transaction) can be shared across multiple threads.

Kevin Crowell
As for (2), and if the table is INNODB, I take it that it is safe to have multiple inserts occurring simultaneously?
Zombies
@Zombies Yes, although I have no experience with InnoDB and Transactions, I believe that should be fine. I see no reason for it not to work.
Kevin Crowell
A: 

Sharing connections between lots of threads is usually implemented by using a connection pool. Every thread can request a connection from the pool, use it for its purposes (one or more transactions, committed or rolled back) and hand it back to the pool once the task is finished.

This is what application servers offer you. They will take care of transactions, too, i. e. when the method that requested the transaction finishes normally, changes are committed, if it throws an exception, the database transaction is rolled back.

I suggest you have a look at Java EE 5 or 6 - it is very easy to use and can even be employed in embedded systems. For easy start, have a look at Netbeans and the Glassfish application server. However the general concepts apply to all application servers alike.

As for InnoDB, it will not have any problems handling lots of transactions. Under the supervision of the app server you can concentrate on the business logic and do not have to worry about half-written updates or anyone seeing updates/inserts before the transaction they originate from has been committed.

InnoDB uses MVCC (multi version concurrency control), effectively presenting each transaction with a snapshot of the whole database as of the time when it was started. You can read more about MVCC here in a related question: Question 812512

Daniel Schneller
This won't be deployed on J2EE. But it will be using a J2SE Connection pool in the future yes. So I take it that I can rollback across all connections in the connection pool...?
Zombies
Yes, MVCC defaults to a transaction isolation level of "repeatable read", meaning that once a transaction has read the first bit of data, it will not see any updates from other transactions, even if these are committed. Only when the current transaction is committed or rolled back the next transaction on this connection will see the new data from everybody else who committed up to that point.
Daniel Schneller
Just to be clear: You will not be able to issue a single "rollback all open transactions" command. But this is usually not what you would want anyway - if so, I think you need to shed some more light on your system, because it would not seem right.
Daniel Schneller
I won't be interested in rollback actually, this is more of a failsafe to not commit bad data if the test in the main thread fails. And what is "MVCC" ?
Zombies
Please see my answer's last paragraph and the link in it.
Daniel Schneller
A: 

Well, as stated in a different answer you can't create a transaction across multiple connections. And you can share the single connection across threads. However you need to be very careful with that. You need to make sure that only one thread is writing to the connection at the same time. You can't just have multiple threads talking across the same connection without synchronizing their activities in some way. Bad things will likely happen if you allow two threads to talk at once (memory corruptions in the client library, etc). Using a mutex or critical section to protect the connection conversations is probably the way to go.

-Don

Don Dickinson
Perhaps, I think I might rethink this by just having the thread wait on the main thread's test to complete before commiting.
Zombies