A transaction is a grouping of tasks that must be processed atomically. If any of the tasks fail, the changes made by any of the successful tasks are rolled back. A failure results in the system returning to its original unmodified state. When we transfer money from a checking account to a savings account, we want both operations to succeed. If the deposit in the savings account fails for any reason,such as power loss, disk failure, or networking failure, the withdrawal of money to the checking account should be reverted. Many years ago, Jim Gray coined the acronym ACID: atomicity, consistency, isolation, and durability as properties of a transaction.
ATOMICITY :-Transactions are atomic in nature—they either commit or roll back. In coding terms, if you band together an arbitrary body of code under the umbrella of a transaction, an unexpected failure will result in all changes made by that block of code being undone. The system is thus left in its original state. If the code completes without any failures, the changes become permanent.
CONSISTENCY:-Consistency refers to the validity of the system—before and after atransaction executes, the system should be consistent with the business rules of the application. It’s the responsibility of the developer to ensure consistency through the use of transactions. The underlying system, such as a database, doesn’t have enough information to know what constitutes a valid state. Whether a transaction succeeds or fails is immaterial—the system will be in a valid state.
ISOLATION:-If there were only one transaction executing at a time, then isolation wouldn’t be a concern.In a given system, any number of transactions can be concurrently manipulating overlapping data. Some of these operations are changing the data, whereas other operations are simply retrieving it for presentation or analyzing it for decision making. There are many shades of gray—for instance, a transaction can be aware of changes being made by another transaction or work in total isolation. The degree to which a transaction is isolated determines its performance characteristics. The more
restrictive isolation levels have poorer performance. Isolation is the guarantee that concurrent users are isolated from each other even if they are using the same database data. Isolation is important to understand as it does not come for free. We can control how isolated transactions are from one another by choosing the right level of isolation. Choosing right level of isolation is critical for the performance of any application. Isolation level is specified on the resource API for instance if the resource is a database we use JDBC API and if the resource is a JMS we use JMS API. In case of JDBC we can use connection.setIsolationLevel() method to set the isolation. Below are different transaction isolation levels-
ATOMICITY :-Transactions are atomic in nature—they either commit or roll back. In coding terms, if you band together an arbitrary body of code under the umbrella of a transaction, an unexpected failure will result in all changes made by that block of code being undone. The system is thus left in its original state. If the code completes without any failures, the changes become permanent.
CONSISTENCY:-Consistency refers to the validity of the system—before and after atransaction executes, the system should be consistent with the business rules of the application. It’s the responsibility of the developer to ensure consistency through the use of transactions. The underlying system, such as a database, doesn’t have enough information to know what constitutes a valid state. Whether a transaction succeeds or fails is immaterial—the system will be in a valid state.
ISOLATION:-If there were only one transaction executing at a time, then isolation wouldn’t be a concern.In a given system, any number of transactions can be concurrently manipulating overlapping data. Some of these operations are changing the data, whereas other operations are simply retrieving it for presentation or analyzing it for decision making. There are many shades of gray—for instance, a transaction can be aware of changes being made by another transaction or work in total isolation. The degree to which a transaction is isolated determines its performance characteristics. The more
restrictive isolation levels have poorer performance. Isolation is the guarantee that concurrent users are isolated from each other even if they are using the same database data. Isolation is important to understand as it does not come for free. We can control how isolated transactions are from one another by choosing the right level of isolation. Choosing right level of isolation is critical for the performance of any application. Isolation level is specified on the resource API for instance if the resource is a database we use JDBC API and if the resource is a JMS we use JMS API. In case of JDBC we can use connection.setIsolationLevel() method to set the isolation. Below are different transaction isolation levels-
Within the Java universe there are four isolation levels, each with different characteristics:
■ Read uncommitted—A transaction can see uncommitted changes from other transactions. This mode does not offer any isolation guarantees but offers the highest performance. A dirty read occurs when application reads data that has not been committed yet. Lets try to understand dirty read with the help of an example:-
■ Read uncommitted—A transaction can see uncommitted changes from other transactions. This mode does not offer any isolation guarantees but offers the highest performance. A dirty read occurs when application reads data that has not been committed yet. Lets try to understand dirty read with the help of an example:-
One application reads an integer X from the database which contains the value X=0. The application adds 10 to X and save it to the database. The database now contains X=10 however the transaction has not been committed yet so the change has not been made permanent yet. Another application reads X from the database. The value it reads is X=10. The first application aborts the transaction which restores the value of X to 0. The other application adds 10 to X and saves it to the database so that X=20. The problem here is that other application reads data from one application that has not been committed. This problem of reading uncommitted data is called dirty read.
■ Read committed—A transaction can see only committed changes, not changes made by other transactions that are still in progress. Read Committed solves the problem of dirty read however introduces the problem of unrepeatable read. Lets try to understand unrepeatable read with the help of an example:-
An application reads data X from the database. Another application overwrites X with new value and commits the change. The first application tries to read X from the database again but founds that the value of X has magically changed. This problem of unmatched reads is called unrepeatable read.
■ Repeatable read—Within a transaction, a read operation may be performed multiple times and each time it’ll return the same result. The transaction won’t see changes made by other transactions even if they commit before this transaction completes. The transaction is essentially working with its own copy of the data. Thus Repeatable read solves the problem of unrepeatable read but introduces another problem called Phantom problem. Lets try to understand Phantom Problem with the help of example:-
One application queries the database using some criteria and retrieves a data set. Another application inserts a new data that would satisfy the same criteria. The application performs the query again for same criteria but magically receives a new set of data. The difference between unrepeatable read and phantom problem is that unrepeatable read occurs when existing data is changed whereas phantoms occur when a new data that didn't existed before is inserted.
■ Serializable—Only one transaction can operate on the data at a given time. This significantly degrades performance because only one transaction can be accessing the data at a time.
A transaction can again be defined as local or global transaction. Global transaction is also know as Distributed Transaction Processing DTP. When transaction involves just one resource its a local transaction. Remember a resource can be any thing, a database, JMS, other legacy system etc. In case of a distributed transaction the transaction involves more than one resource. JDBC only supports local transaction. DTP is not supported by JDBC. In case of DTP transaction manager is responsible for communicating with one or more resource manager which ultimately communicates with the underlying resource. DTP is supported by Java Transaction API or JTA. JTA is JAVA EE specification and normally does not work with JAVA SE specification although there are few open source like JOTM available for SE.
JTA provides the core of transaction support in Java. It defines interface between a transaction manager and other parties like resource manager and application server. JTA consists of three interfaces- javax.transaction.xa.XAResource, javax.transactoin.TransactionManager and javax.transaction.UserTransaction. As a devloper we are mostly concerned about TransactionManager as we mostly work on this interface only.
Two Phase Commit:-The two-phase commit protocol is used in situations where a transaction spans multiple resources. As its name suggests, a two-phase commit has two phases. In the first phase the transaction manager polls the resource managers asking them if they’re ready to commit. If all of the resource managers reply affirmatively, the transaction manager then issues a commit message to each resource manager. If any one of the resource managers responds negatively, the transaction is rolled back. Each resource manager is responsible for maintaining a transaction log so that if anything happens, the transaction can be recovered.
Is it possible that a resource manager could vote to commit but then subsequently fail?The answer is yes; this can and does happen for a variety of reasons. Between the time that the data is polled and the commit is issued, a shutdown request might be issued to the database or a network connection might be lost. Often, though, a time-out might be exceeded due to high load and the transaction manager makes a unilateral decision to roll back the transaction. In this case a heuristic exception is thrown. There are three different heuristic exceptions that could be thrown: Heuristic- CommitException, HeuristicMixedException, and HeuristicRollbackException. A HeuristicCommitException is thrown when a request is issued to roll back but a heuristic decision is made to commit. A HeuristicMixedException is thrown when some resource managers commit but others fail. In this situation the system is now in an invalid state that will require intervention. A HeuristicRollbackException is thrown when a heuristic decision is made and all of the resources have been rolled back. With this exception, the client should resubmit the request. These exceptions need to be caught and handled by the application. One important thing to remember is that failures can happen on any end. The container with the transaction manager may fail (system shutdown), leaving the resource managers hanging. In this case, the individual resource managers may make a decision on their own to roll back—they can’t keep resources locked forever. When the transaction manager comes back up, it’ll attempt to complete the transaction
JTA is designed to perform optimally whether we are using a single resource or a dozen. There are a number of common optimizations that are implemented by every transaction manager. These optimizations help ensure that JTA won’t be a bottleneck for the application. These optimizations can be summarized as one-phase, presumed abort, and read-only. In the previous section we discussed how a two-phase commit is implemented. A two-phase commit is needed for situations in which two or more resources are participating in a transaction. But if only one resource is being used, the transaction manager will use only a single commit phase. The voting phase will be skipped, because it serves no purpose in this situation. One or more resources may choose to abort during the voting phase. When this occurs, it no longer makes sense to poll the other resource managers. Once a rollback has been detected, the transaction manager will immediately notify resource managers that haven’t been polled to roll back. There’s no sense in asking these resource managers for their commit/rollback decision because their response is irrelevant. Resources that are read-only and didn’t update any data don’t need to take part in the commit process. A resource manager will report to the transaction manager that it doesn’t have any changes to commit. The transaction manager will then skip over the resource during the voting and commit phase, thus eliminating several extra steps.
In this blog I have covered the basics of Transactions with respect to JAVA. In my next blog I will be explaining about transaction support for EJB along with BMT and CMT.
Thanks for reading,
A transaction can again be defined as local or global transaction. Global transaction is also know as Distributed Transaction Processing DTP. When transaction involves just one resource its a local transaction. Remember a resource can be any thing, a database, JMS, other legacy system etc. In case of a distributed transaction the transaction involves more than one resource. JDBC only supports local transaction. DTP is not supported by JDBC. In case of DTP transaction manager is responsible for communicating with one or more resource manager which ultimately communicates with the underlying resource. DTP is supported by Java Transaction API or JTA. JTA is JAVA EE specification and normally does not work with JAVA SE specification although there are few open source like JOTM available for SE.
JTA provides the core of transaction support in Java. It defines interface between a transaction manager and other parties like resource manager and application server. JTA consists of three interfaces- javax.transaction.xa.XAResource, javax.transactoin.TransactionManager and javax.transaction.UserTransaction. As a devloper we are mostly concerned about TransactionManager as we mostly work on this interface only.
Two Phase Commit:-The two-phase commit protocol is used in situations where a transaction spans multiple resources. As its name suggests, a two-phase commit has two phases. In the first phase the transaction manager polls the resource managers asking them if they’re ready to commit. If all of the resource managers reply affirmatively, the transaction manager then issues a commit message to each resource manager. If any one of the resource managers responds negatively, the transaction is rolled back. Each resource manager is responsible for maintaining a transaction log so that if anything happens, the transaction can be recovered.
Is it possible that a resource manager could vote to commit but then subsequently fail?The answer is yes; this can and does happen for a variety of reasons. Between the time that the data is polled and the commit is issued, a shutdown request might be issued to the database or a network connection might be lost. Often, though, a time-out might be exceeded due to high load and the transaction manager makes a unilateral decision to roll back the transaction. In this case a heuristic exception is thrown. There are three different heuristic exceptions that could be thrown: Heuristic- CommitException, HeuristicMixedException, and HeuristicRollbackException. A HeuristicCommitException is thrown when a request is issued to roll back but a heuristic decision is made to commit. A HeuristicMixedException is thrown when some resource managers commit but others fail. In this situation the system is now in an invalid state that will require intervention. A HeuristicRollbackException is thrown when a heuristic decision is made and all of the resources have been rolled back. With this exception, the client should resubmit the request. These exceptions need to be caught and handled by the application. One important thing to remember is that failures can happen on any end. The container with the transaction manager may fail (system shutdown), leaving the resource managers hanging. In this case, the individual resource managers may make a decision on their own to roll back—they can’t keep resources locked forever. When the transaction manager comes back up, it’ll attempt to complete the transaction
JTA is designed to perform optimally whether we are using a single resource or a dozen. There are a number of common optimizations that are implemented by every transaction manager. These optimizations help ensure that JTA won’t be a bottleneck for the application. These optimizations can be summarized as one-phase, presumed abort, and read-only. In the previous section we discussed how a two-phase commit is implemented. A two-phase commit is needed for situations in which two or more resources are participating in a transaction. But if only one resource is being used, the transaction manager will use only a single commit phase. The voting phase will be skipped, because it serves no purpose in this situation. One or more resources may choose to abort during the voting phase. When this occurs, it no longer makes sense to poll the other resource managers. Once a rollback has been detected, the transaction manager will immediately notify resource managers that haven’t been polled to roll back. There’s no sense in asking these resource managers for their commit/rollback decision because their response is irrelevant. Resources that are read-only and didn’t update any data don’t need to take part in the commit process. A resource manager will report to the transaction manager that it doesn’t have any changes to commit. The transaction manager will then skip over the resource during the voting and commit phase, thus eliminating several extra steps.
In this blog I have covered the basics of Transactions with respect to JAVA. In my next blog I will be explaining about transaction support for EJB along with BMT and CMT.
Thanks for reading,
No comments:
Post a Comment