Having the following problem of understanding why a connection session exists that goes on for 6 hours and also holding a lock and breaking the thread the question is rased if a connection of XADataSource (Oracle driver) needs a Java reference at all to be kept alive.
In terms of distributed transaction set to kept till it is explicitly ended (keep-xa-conn-till-tx-complete=true) I wonder how a driver could decide wether to close connection and commit a transaction once the GC recycled the connection. Is there even a way for the DBMS to do so?
So the question goes how does a DBMS decide wether to abandon a distributed transaction or not.
The DBMS does not decide to end the transaction, the transaction manager does.
The transaction manager is set up to run in your application containers, whether they are Spring, J2EE application servers, or something else. They have to "know" they are distributed transaction managers by being configured correctly. In a distributed transaction environment, where you have multiple transactional applications and/or services interacting to complete a transaction, they must all be able to support distributed transactions to make proper use of the XADataSources and send the right signals up and down the chain for commit vs rollback.
Presuming that you have the above situation, multiple applications and/or services participating in a distributed transaction, it sounds as if one of them is not configured correctly. Something in the chain is not truly a distributed transaction, so that when it completes it's only completing locally and not sending the signal back down the line. So the distributed transaction never completes, holding the connection open.
Check the configuration of every application and/or service participating in the transaction. Add logging output on each that details whether the transaction is a distributed one or not. If you can't do that, then dd logging output to each that records the start and end of the transaction. Find the latest point in the sequence of actions where you see an open-transaction but not a close-transaction. If you see that, it's likely the node right after it in the chain that is doing something wrong.
Good luck.
Related
I'm wondering what would be the best way of implementing a UnitOfWork pattern on top of JDBC when using repository pattern.
I want to use UOW to commit or rollback commands from potentially multiple different repositories. So what I came up with is that the repositories get the connection they are going to execute commands on from the UOW object and let that manage committing or rolling it back.
Now the question is how shall the UOW manage connections? Shall it get one connection on start of a cycle and share it with all repositories when they call for a connection and at the end either commit or roll it back. Or shall it let the datasource manage the connections, and keep a reference to all the connections obtained in one session in order to be able to commit or rollback all of them?
Which way I use the best out of connection pooling and will have less trouble in managing connections?
Maybe its also worth noting that I use a single threaded approach, meaning a whole cycle (single UOW) is run on single thread and there is no fancy multithreading management required neither in UOW nor in repositories. However multiple cycles may run in parallel each on its own thread.
I am using Hibernate with c3p0 for connection pooling. Since I am working in a multisharded database environment and the possibility of shards' downtime is a realistic use case scenario (by means external to the application at hand, e.g. someone just taking the shard down for whatever reason), I am trying to have c3p0 explicitly close the Hibernate session once it detects that the database connection is down so that I can skip the particular shard's session in my multi-shard scan.
Is there a way to configure c3p0 to notify Hibernate, by invoking Session.close() once it finds out that the connection is down so that calling Session.isOpen() can return a meaningful boolean?
RELATED: Preemptively and gracefully check that org.hibernate.Session is still connected (via c3p0)
the short answer is no, c3p0 won't help you here.
it sounds like (looking here and at your previous question) you are doing something that works at cross-purposes to c3p0, that is you are holding long-lived Sessions rather than creating Sessions on an as-needed basis and then destroying them promptly. that kind of thing is very fragile. it is the architecture Connection pools exist to avoid.
your best choice, IMO, would be "don't do that". don't ever cache Sessions at all. then ordinary Connection testing (perhaps with checkoutTimeout set too) will resolve the problem. if a shard is down, attempts to acquire a Connection will fail, and you can skip the shard if that's the best workaround.
c3p0 knows nothing whatsoever about hibernate. c3p0's author is grateful to hibernate for popularizing his (my) library, but c3p0 has no idea what a Session is, just a Connection. the only way that c3p0 could help you a little bit, in theory, would be that it could report to you an event when it notices that a database is down (which might be quite promptly or quite slowly depending on your configuration). you could respond to the event by close()ing sessions.
unfortunately, c3p0 doesn't (yet) offer hooks through which users could respond to acquisition failures. it might — that's a feature i'm thinking about adding for 0.9.6. but it doesn't now. however, it would be pretty trivial to implement something that polls your shards and closes their Sessions yourself. all c3p0 would do to notice outages would be to call DriverManager.getConnection( ... ) or dataSource.getConnection()and observe Exceptions. you can do that yourself!
i still strongly recommend the first solution, though. get rid of the long-lived Session objects.
Recently I was asked a question which left me thinking..want to get the community views on the same question.
I have a CustomerEJB which has say a createCustomer method. My EJB is exposed as a web service and hence createCustomer is one of its operations.
When a request hits createCustomer, 2 operations need to be performed
An INSERT SQL query into the database which may be adding certain data into db that came in input request
creation of a text file, say .txt in the file system.
Now the question is I want to couple these two tasks into a transaction. If any one task fails, I rollback the other task as well.
Without mentioning any hot technologies, like Spring/Hibernate what is the approach I can follow for Transaction management
My thoughts:
1. I can use JTA, demarcate the transaction boundaries and perform commit and rollback accordingly. JDBC can be used for the SQL task
2. I can use DAOs
Inviting your kind suggestions/comments
You would need to wrap the file creating in a XA capable JCA connector (not sure whether there's a ready made one out there, a quick good only found this fsconnector which doesn't support transactions yet), and use an XA driver for your DB transaction (most DBs will will be able handle this) and then wrap your EJB in an XA transaction (should be straightforward).
As long as both resources can handle the XA transactions, you'll get the benefit of 2-phase commits, which is what you're after.
I think this is a fairly common question: how to put my business logic in a global transaction in distributed systems environment? Cite an example, I have a TaskA containing couples of sub tasks:
TaskA {subtask1, subtask2, subtask3 ... }
each of these subtasks may execute on local machine or a remote one, I hope TaskA executes in an atomic manner(success or fail) by means of transaction. Every subtask has a rollback function, once TaskA thinks the operation fails(because one of subtask fails), it calls each rollback function of subtasks. Otherwise TaskA commits the whole transaction.
To do this, I follow "Audit trial" transaction pattern to have a record for each subtask, so TaskA can know operation results of subtasks then decide rollback or commit. This sounds like simple, however, the hard part is how to associate each subtask to the global transaction?
When TaskA begins, it starts a global transaction about which subtask knows nothing. To make subtask aware of it, I have to pass the transaction context to every invocation of subtask. This is really dreadful! My subtask may either execute in a new thread or execute in remote by sending a message through AMQP broker, it's hard to consolidate the way of context propagation.
I did some research like "Transaction Patterns - A Collection of Four Transaction Related Patterns", "Checked Transactions in an Asynchronous Message Passing Environment", none of these solve my problem. They either don't have practical example or don't solve the context propagation issue.
I wonder how people solve this? as this sort of transaction must be common in enterprise software.
Is X/Open XA only the solution for this? Can JTA help here(I have't look into JTA as most stuff for it relate to database transaction, and I am using Spring, I don't want to involve another Java EE application server in my software).
Can some expert share some thoughts with me? thank you.
Conclusion
Arjan and Martin gave out really good answers, thank you.
Finally I didn't go with this way. After more research, I chose another pattern "CheckPoint" 1.
Looking into my requirement, I found my intention to "Audit Trial Transaction Pattern" is to know which level the operation has proceeded to, if it's failed, I can restart it at the failed spot after reloading some context. Actually this is not transaction, it didn't rollback other successful steps after failure. This is essence of CheckPoint pattern.
However, studying distributed transaction stuff makes me learned lot of interesting things. Apart from what Arjan and Martin have mentioned. I also suggest people digging into this area take a look at CORBA which is a well-known protocol for distributed system.
You're right, you need two-phase commit support thanks to a XA transaction manager provided by the JTA API.
As far as I know Spring does not provide a transaction manager implementation itself. The JtaTransactionManager only delegates to existing implementation usually provided from JavaEE implementations.
So you will have to plugin a JTA implementation into Spring to get effective job done. Here are some proposals:
JOTM
JBossTS based on Arjuna.
Atokimos
Then you will have to implement your resource manager to support two-phase commit. In the JavaEE worlds, it consists in a resource adapter packaged as a RAR archive. Depending on the type of resource, the following aspects are to read/implement:
XAResource interface
JCA Java Connector Architecture mainly if a remote connection is involved
JTS Transaction Service if transaction propagation between nodes is required
As examples, I recommend you to look at implementations for the classical "transactions with files" issue:
the transactional file manager from JBoss Transactions
XADisk project
If you want to write your own transactional resource, you indeed need to implement an XAResource and let it join an ongoing transaction, handle prepare and commit requests from the transaction manager etc.
Datasources are the most well known transactional resources, but as mentioned they are not the only ones. You already mentioned JMS providers. A variety of Caching solutions (e.g. Infinispan) are also transactional resources.
Implementing XAResources and working with the lower level part of the JTA API and the even lower level JTS (Java Transaction Service) is not a task for the faint of heart. The API can be archaic and the entire process is only scarcely documented.
The reason is that regular enterprise applications creating their own transactional resources is extremely rare. The entire point of being transactional is to do an action that is atomic for an external observer.
To be observable in the overwhelming majority of cases means the effects of the action are present in a database. Nearly each and every datasource is already transactional, so that use case is fully covered.
Another observable effect is whether a message has been send or not, and that too is fully covered by the existing messaging solutions.
Finally, updating a (cluster-wide) in memory map is yet another observable effect, which too is covered by the major cache providers.
There's a remnant of demand for transactional effects when operating with external enterprise information systems (EIS), and as a rule of thumb the vendors of such systems provide transaction aware connectors.
The shiver of use cases that remain is so small that apparently nobody ever really bothered to write much about it. There are some blogs out there that cover some of the basics, but much will be left to your own experimentation.
Do try to verify for yourself if you really absolutely need to go down this road, and if your need can't be met by one of the existing transactional resources.
You could do the following (similar to your checkpoint strategy):
TaskA executes in a (local) JTA transaction and tries to reserve the necessary resources before it delegates to your subtasks
Subtask invocations are done via JMS/XA: if step 1 fails, no subtask will ever be triggered and if step 1 commits then the JMS invocations will be received at each subtask
Subtasks (re)try to process their invocation message with a JMS max redelivery limit set (see your JMS vendor docs on how to do this)
Configure a "dead letter queue" for any failures in 3.
This works, assuming that:
-retrying in step 3 makes sense
-there is a bit of human intervention needed for messages in the dead letter queue
If this is not acceptable then there is also TCC: http://www.atomikos.com/Main/DownloadWhitepapers?article=TccForRestApi.pdf - this can be seen as a "reservation" pattern for REST services.
Hope this helps
Guy
http://www.atomikos.com
I have an application - more like a utility - that sits in a corner and updates two different databases periodically.
It is a little standalone app that has been built with a Spring Application Context. The context has two Hibernate Session Factories configured in it, in turn using Commons DBCP data sources configured in Spring.
Currently there is no transaction management, but I would like to add some. The update to one database depends on a successful update to the other.
The app does not sit in a Java EE container - it is bootstrapped by a static launcher class called from a shell script. The launcher class instantiates the Application Context and then invokes a method on one of its beans.
What is the 'best' way to put transactionality around the database updates?
I will leave the definition of 'best' to you, but I think it should be some function of 'easy to set up', 'easy to configure', 'inexpensive', and 'easy to package and redistribute'. Naturally FOSS would be good.
The best way to distribute transactions over more than one database is: Don't.
Some people will point you to XA but XA (or Two Phase Commit) is a lie (or marketese).
Imagine: After the first phase have told the XA manager that it can send the final commit, the network connection to one of the databases fails. Now what? Timeout? That would leave the other database corrupt. Rollback? Two problems: You can't roll back a commit and how do you know what happened to the second database? Maybe the network connection failed after it successfully committed the data and only the "success" message was lost?
The best way is to copy the data in a single place. Use a scheme which allows you to abort the copy and continue it at any time (for example, ignore data which you already have or order the select by ID and request only records > MAX(ID) of your copy). Protect this with a transaction. This is not a problem since you're only reading data from the source, so when the transaction fails for any reason, you can ignore the source database. Therefore, this is a plain old single source transaction.
After you have copied the data, process it locally.
Setup a transaction manager in your context. Spring docs have examples, and it is very simple. Then when you want to execute a transaction:
try {
TransactionTemplate tt = new TransactionTemplate(txManager);
tt.execute(new TransactionCallbackWithoutResult(){
protected void doInTransactionWithoutResult(
TransactionStatus status) {
updateDb1();
updateDb2();
}
} catch (TransactionException ex) {
// handle
}
For more examples, and information perhaps look at this:
XA transactions using Spring
When you say "two different databases", do you mean different database servers, or two different schemas within the same DB server?
If the former, then if you want full transactionality, then you need the XA transaction API, which provides full two-phase commit. But more importantly, you also need a transaction coordinator/monitor which manages transaction propagation between the different database systems. This is part of JavaEE spec, and a pretty rarefied part of it at that. The TX coordinator itself is a complex piece of software. Your application software (via Spring, if you so wish) talks to the coordinator.
If, however, you just mean two databases within the same DB server, then vanilla JDBC transactions should work just fine, just perform your operations against both databases within a single transaction.
In this case you would need a Transaction Monitor (server supporting XA protocol) and make sure your databases supports XA also. Most (all?) J2EE servers comes with Transaction Monitor built in. If your code is running not in J2EE server then there are bunch of standalone alternatives - Atomicos, Bitronix, etc.
You could try Spring ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html that supports distributed db transaction. This could be a better alternative to XA