In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/03 Report--
Basic configuration of spring transactions
See: http://www.cnblogs.com/leiOOlei/p/3725911.html
Spring transaction propagation mechanism
See: http://www.cnblogs.com/aurawing/articles/1887030.html
Briefly talk about the difference between new and nested.
When using new, the commit or rollback of the outer transaction has nothing to do with the transaction of new. When using nested, whether the inner transaction is ultimately committed or rolled back depends on the outer transaction. See the following table.
Transaction propagation configuration outer transaction (set aplom1) inner transaction (set transaction 2) final result new commit commit APC1 & & b=2new commit rollback a=1new rollback a=1new rollback b=2new rollback nothing changes nested commit commit AQ1 & b=2nested commit rollback AQ1 (in this case requires an additional configuration:) nested rollback commit nothing changes nested rollback nothing changes spring transaction isolation mechanism
See: Isolation Level (transaction isolation level):
Serializable: the most stringent level, where transactions are executed serially and consume the most resources; REPEATABLE READ: ensures that one transaction does not modify data that has been read by another transaction but not committed (rollback). It avoids the situation of "dirty read" and "non-repeatable read", but brings more performance loss. READ COMMITTED: the default transaction level of most mainstream databases ensures that one transaction does not read the modified but uncommitted data of another parallel transaction, avoiding "dirty reading". This level applies to most systems. Read Uncommitted: ensures that illegal data will not be read during reading. The isolation level is to deal with the concurrency of multiple transactions.
We know that parallelism can improve database throughput and efficiency, but not all concurrent transactions can be run concurrently, which needs to be judged by looking at the serializability conditions of database textbooks.
I won't elaborate here.
Let's first talk about the unpleasant things that may happen in concurrency.
Dirty reads-- reads dirty data. In other words, if the uncommitted (and still cached) data of transaction An is read by transaction B, if transaction A fails to roll back, it will cause the data read by transaction B to be wrong. Non-repeatable reads-- data cannot be read repeatedly. For example, the value of total- is read in two places in transaction A. On the first reading, total is 100. then transaction B changes the data of total to 200. transaction A reads it again, and it turns out that total becomes 200. as a result, transaction A data is confused. The phantom reads-- illusion of reading data, similar to non-repeatable reads, is also a problem of multiple read inconsistencies in the same transaction. But the inconsistency of non-repeatable reads is due to the change of the dataset he wants to fetch (such as the data of total), but the inconsistency of the data that phantom reads wants to read is not the change of the dataset he wants to read, but the change of his conditional dataset. For example, Select account.id where account.name= "ppgogo*" reads six eligible id for the first time, and when it is read the second time, because transaction b changes the name of an account from "dd" to "ppgogo1", seven data are fetched. -- Dirty readsnon-repeatable readsphantom readsSerializable won't REPEATABLE READ won't READ COMMITTED won't Read Uncommitted will DEFALT (use the default isolation level of the underlying database)? Spring transaction Management other configuration readOnly
Mark transaction read-only. Read-only transactions are optimized; however, data can actually be written in read-only transactions.
Timeout
Transaction timeout
RollbackFor/rollbackForClassName
Mark which exceptions will cause a rollback. By default, all RuntimeException throws a rollback; all other checked-exception does not throw a rollback. If you need to roll back for some checked-exception, you need to configure rollbackFor or rollbackForClassName for the transaction
NoRollbackFor/noRollbackForClassName
Mark which exceptions do not cause a rollback. By default, all RuntimeException throws a rollback; all other checked-exception does not throw a rollback. If you need to prevent some RuntimeException from being rolled back, you need to configure noRollbackFor/noRollbackForClassName for the transaction.
Basic principles of spring transaction mechanism aop
Regardless of configuration mode or annotation mode, spring is based on spring aop for transaction management.
That is, a dynamic proxy is generated at the transaction pointcut. Manage transactions in the agent (open, propagate, commit, rollback, etc.). See the following two pictures:
Both figures show the thread stack when the isLocked () method is called. As you can see, the second chapter diagram invokes the isLocked () method through a dynamic proxy, while the first figure is not.
The dynamic proxy approach simplifies code development; however, it also introduces some minor problems. I'll talk about it later.
Thread context
Spring places transaction-related stateful data (database connections, hibernate's session, and so on) in the thread context (ThreadLocal). Therefore, the propagation relationship between transactions and the timing of transaction opening and closing are very similar to the method call stack in a thread.
In addition, because transactions are thread-related, the current transaction management of spring cannot allow multiple child threads to run within the same transaction.
How to test
First, let's take a look at how to determine whether transactions are used at runtime and how transactions are propagated.
First add the following configuration to log4j. Strictly speaking, as long as the log of org.springframework.transaction.support.AbstractPlatformTransactionManager is recorded. Another logger is used to record the SQL, and it can also be replaced with another logger.
Then run the transaction-related code:
@ Testpublic void test () {/ / this method uses the default propagation method (REQUIRED) this.lockServiceByDB.tryLock (LockName.EVENT_LOAN, "23424"); / / this method uses REQUIRES_NEW 's propagation method this.lockServiceByDB.isLocked (LockName.EVENT_LOAN, "23424");}
You can find the following logs:
2016-07-06 18 PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 01 DEBUG AbstractPlatformTransactionManager.getTransaction Creating new transaction with name [cn.youcredit.thread.bizaccount.service.impl.LockServiceByDBTestBySpring.test]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT;',-cn.youcredit.thread.common.exception.ServiceException
[medium outline]
2016-07-06 18 purl 01 purl 11297 DEBUG AbstractPlatformTransactionManager.handleExistingTransaction Participating in existing transaction
2016-07-06 18 purl 01 purl 11309 DEBUG SqlStatementLogger.logStatement
Select count (1) as col_00 from dblocks dblock0 where dblock0.lockName=? And dblock0.uniKey=?
2016-07-06 18 purl 01 purl 11325 DEBUG SqlStatementLogger.logStatement
Insert into db_locks (lockName, lockTimeAsLong, uniKey) values (?
[medium outline]
2016-07-06 18 cn.youcredit.thread.bizaccount.service.impl.LockServiceByDB.isLocked 01 DEBUG AbstractPlatformTransactionManager.handleExistingTransaction Suspending current transaction, creating new transaction with name [cn.youcredit.thread.bizaccount.service.impl.LockServiceByDB.isLocked]
[medium outline]
2016-07-06 18 purl 01 purl 11335 DEBUG SqlStatementLogger.logStatement
Select count (1) as col_00 from dblocks dblock0 where dblock0.lockName=? And dblock0.uniKey=?
2016-07-06 18 purl 01 purl 11337 DEBUG AbstractPlatformTransactionManager.processCommit Initiating transaction commit
2016-07-06 18 entityKeys= 01 PersistenceContext 11337 DEBUG HibernateTransactionManager.doCommit Committing Hibernate transaction on Session [SessionImpl (PersistenceContext [entityKeys= [], collectionKeys= []]; ActionQueue [insertions=org.hibernate.engine.spi.ExecutableList@1a9ea4d9 updates=org.hibernate.engine.spi.ExecutableList@59ca0db6 deletions=org.hibernate.engine.spi.ExecutableList@33293dac orphanRemovals=org.hibernate.engine.spi.ExecutableList@384841e3 collectionCreations=org.hibernate.engine.spi.ExecutableList@571f925f collectionRemovals=org.hibernate.engine.spi.ExecutableList@5eb192b7 collectionUpdates=org.hibernate.engine.spi.ExecutableList@248f1090 collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5eb20abb unresolvedInsertDependencies=UnresolvedEntityInsertActions [])]
[medium outline]
2016-07-06 18 purl 01 purl 11339 DEBUG AbstractPlatformTransactionManager.cleanupAfterCompletion Resuming suspended transaction after completion of inner transaction
2016-07-06 18 purl 01 purl 11340 DEBUG AbstractPlatformTransactionManager.proce***ollback Initiating transaction rollback
2016-07-06 18 odel.auth.UserInfo#system 01 DEBUG HibernateTransactionManager.doRollback Rolling back Hibernate transaction on Session 11340 DEBUG HibernateTransactionManager.doRollback Rolling back Hibernate transaction on Session [PersistenceContext [entityKeys = [EntityKey [cn.youcredit.thread. Common.m odel.auth.UserInfo#system], EntityKey [cn.youcredit.thread.bizaccount.bean.DBLock#139], EntityKey [cn.youcredit.thread.common.model.auth.UserGroupInfo#500], collectionKeys= [] ActionQueue [insertions=org.hibernate.engine.spi.ExecutableList@2f90ad92 updates=org.hibernate.engine.spi.ExecutableList@4710332d deletions=org.hibernate.engine.spi.ExecutableList@7930de44 orphanRemovals=org.hibernate.engine.spi.ExecutableList@52891a77 collectionCreations=org.hibernate.engine.spi.ExecutableList@785fd189 collectionRemovals=org.hibernate.engine.spi.ExecutableList@3e900cf4 collectionUpdates=org.hibernate.engine.spi.ExecutableList@412d379c collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5b6dc76c unresolvedInsertDependencies=UnresolvedEntityInsertActions []])]
From the log, you can clearly see the process of transaction operation and propagation:
First, when you run the LockServiceByDBTestBySpring.test () method, a new transaction is created. This is the transaction logic of SpringJUnit4Cla***unner, that is, each unit test starts a transaction, and by default, the transaction is rolled back. Then, when executing to the this.lockServiceByDB.tryLock () method, because the propagation is REQUIRED, it will join the current existing transaction and execute two sql. Then execute the this.lockServiceByDB.isLocked () method. Because the transaction propagation of this method is REQUIRES_NEW, the current transaction is suspended, a new transaction is created, and a SQL is executed in the new transaction. After the new transaction is executed and committed, the suspended upper-level transaction is resumed. And continue to execute. Since there is no other logic or code later, the outer transaction starts to be rolled back. FAQ transactions are marked on protcted or private methods, causing the transaction to fail
Spring's transaction annotations are valid only for public methods and are not valid for protcted, friendly (default), and private methods. If you mark transaction comments on these later methods, the effect is tantamount to no marking.
Improper inheritance of annotations, resulting in transaction invalidation
The basic inheritance relationships of Java annotations are as follows. There is a meta-annotation of Inherited on the Transactional comment of spring.
-not writing @ Inherited: can the comments on the class of the subclass of @ Inherited inherit from the class of the parent class? Can the subclass method implement the abstract method on the parent class, can this method inherit annotations? Whether the subclass method inherits the method on the parent class, can this method inherit the annotation? Can the subclass method overwrite the method on the parent class, can this method inherit annotations? No. No.
For example, in the following code, although Son declares a transaction at the class level, its tryLocked () method does not start a new transaction. Because it does not declare a transaction in the parent class.
Public class Father {public void tryLocked () {}} @ Transactional (REQUIRES_NEW) public class Son extends Father {} is called in this mode, resulting in transaction invalidation
For the dynamic agent of spring aop, the proxied instance and method is a "black box". Transaction management can only be done outside the "black box". The this call is the invocation logic inside the black box and the agent is not aware of it.
Therefore, in code like the one below, the isLocked () method does not start a new transaction.
@ Transactional (REQUIRES_NEW) public void isLocked () {. } @ Transactional () public void tryLock () {this.isLocked (); … } transaction and query
Although the query operation does not update the data, the query also requires transactions. Especially for hibernate.
When hibernate manipulates the database, you need to get a session of hibernate. And this session is also managed by HibernateTransactionManager. Like other stateful data, it is managed in the same way as in ThreadLocal. If there is no transaction manager on the thread, you will not get the session. When hibernate makes a query, it will report an error:
Org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
At org.springframework.orm.hibernate4.SpringSessionContext.currentSession (SpringSessionContext.java:134) ~ [spring-orm-4.2.2.RELEASE.jar:4.2.2.RELEASE]
Sometimes a query can be executed without writing a transaction comment, so it is likely that the transaction has been opened by default or "secretly" somewhere. For example, unit tests that inherit SpringTestCase will turn on transactions by default. Or in the web environment, the previously bound transaction manager is left on the thread in the thread pool.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.