Transaction propagation mechanism of isolation level and spring in spring transaction

Source: Internet
Author: User

Transaction is the so-called business, popular understanding is one thing. From childhood, parents educate us, do things to the beginning and finish, not halfway. The same is true of business, which cannot be done in general, or done or not. In other words, a transaction must be an indivisible whole, like the atoms we learn in chemistry, atoms are the smallest units that make up a substance. Thus, the first characteristic of a transaction is summed up: atomicity (atomicity). I'm not a mystery at all.

Especially in the database domain, the transaction is a very important concept, in addition to atomicity, it has an extremely important feature, that is: consistency (consistency). That is, the data is not destroyed after the database operation has been performed. For example, if you transfer from a account to a B account, it is not possible to deduct money from a account, and B account does not add money. If there is such a thing, you will be very angry, what Diao bank Ah!

When we write an UPDATE statement and commit to the database for an instant, it is possible that someone else has submitted a DELETE statement to the database. Maybe we're all working on the same record, and we can imagine that if we don't get a little bit of control, it's going to be a big problem. We must ensure that database operations are "isolated" (sometimes isolated between threads), without any interference between them. This is: isolation (isolation). To really do the operation between the total without any interference is difficult, so, every day to work soy sauce database experts, began to think, "we have to develop a standard, so that the database manufacturers are supporting our specifications!" ", this specification is: the level of separation of affairs (Transaction isolation Levels). can define such a good code really is not easy, in fact, plainly on the four levels:

    1. read_uncommitted
    2. read_committed
    3. Repeatable_read
    4. SERIALIZABLE

Don't translate, it's just a code name. From the top down, the level is getting higher, the concurrency is getting worse, the security is getting higher and the reverse is reversed.

When we execute an INSERT statement, the database must ensure that a single piece of data is permanently stored on disk, which is also an attribute of the transaction: Persistence (durability).

To sum up, the above mentioned the 4 characteristics of the transaction, the first letter of their English words together is: acid, this is the legendary "Transaction ACID characteristics"!

Really is a very good character Ah! These 4 characteristics are the cornerstone of transaction management and must be thoroughly understood. Also make clear, who is the boss among these four guys?

In fact, it is clear that the atom is the basis, isolation is the means, persistence is the goal, the real boss is consistency. Data inconsistency, the equivalent of "The lake chaos, rogue wearing a bra." So, these three boys are following the "consistency" this boss mixed, for his wholehearted service.

Of these four guys, the hardest thing to understand is not consistency, but isolation. Because it is an important means of ensuring consistency, is the tool, use it can not have the slightest mistake, or the consequences of self-esteem! No wonder database industry experts are going to study the so-called transaction isolation level. In fact, the definition of these four levels is to solve the problem caused by the high concurrency of data, then what are the problems?

    1. Dirty Read (dirty reading)
    2. unrepeatable Read (non-repeatable)
    3. Phantom Read (Phantom Read)

First look at "dirty reading", see "dirty" the word, I think of nausea, dirty. How can data be dirty? In fact, we often say "junk data". For example, there are two transactions, which are executed concurrently (that is, competition). Take a look at the form below and you'll understand what I'm saying:

time
Transaction A (deposit)
transaction B (withdrawal)
T1
Start Affairs

T2

Start a transaction
T3

Enquiry Balance (1000 RMB)
T4

Withdraw 1000 yuan (balance 0 yuan)
T5
Enquiry Balance (0 RMB )

T6

undo Transaction (Balance restored to $1000)
T7
Deposit $500 (balance $500)

T8
Commit a transaction


The balance should be 1500 yuan! See T5 time, Transaction A at this point the query balance of 0 yuan, this data is dirty data, it is the result of transaction B, the obvious transaction has not been isolated, infiltration over, chaos.

so dirty reading this thing is very undesirable, must be solved! It is the hard truth to isolate the transactions between them.

What about the 2nd, which cannot be repeated? Or a similar example is used to illustrate:

time
Transaction A (deposit)
transaction B (withdrawal)
T1
Start a transaction

T2

Start a transaction
T3

Enquiry Balance (1000 RMB)
T4
Enquiry Balance (1000 RMB)

T5

Withdraw 1000 yuan (balance 0 yuan)
T6

Commit a transaction
T7
Enquiry Balance (0 RMB)


Transaction A In fact, in addition to the query two times, nothing else to do, the result of money from 1000 to 0, which is repeated reading. It is conceivable that it was done by others, not by me. In fact, this is also reasonable, after all, transaction B commits the transaction, the database will persist the results, so that transaction A again read nature changed.

This kind of phenomenon is basically understandable, but it is not allowed in some perverted scenes. After all, this phenomenon is also caused by the absence of segregation between transactions, but we seem to be able to ignore this problem.

The last one, the Phantom read. I'll go! Phantom the word "ghost, Ghost"? When I first saw this word, I was really shocked by my little brother. No wonder this is translated into "phantom reading", can not be translated into "ghost reading", "ghost reading" it. In fact, the meaning is that ghosts are reading, not people reading, or why, it is not clear why, it changed, very dizzy, really dizzy. Let's use an example to speak:

time
Transaction A (statistics total deposits)
Transaction B (deposit)
T1
Start a transaction

T2

Start a transaction
T3
Total deposit of statistics (10000 RMB )

T4

Deposit $100
T5

Commit a transaction
T6
Total deposit of statistics (10100 RMB )


Bank staff, each time the total deposit statistics, see the different results. But it is also quite normal, the total deposit has increased, it is certain that someone is saving at this time. But if the banking system is really designed like this, it's done. This is also caused by a lack of isolation of the transaction, but it seems normal, understandable, and permissible for most application systems. The disgusting systems in the bank, which are very demanding, count and even isolate all the other operations, even if the isolation level is very high (estimated to SERIALIZABLE level).

To summarize, the above mentioned the transaction concurrency caused by the read data related problems, each with a sentence to describe:

    1. dirty reads: Transaction a reads the uncommitted data from transaction B, and then does other things on that basis.
    2. non-REPEATABLE READ: Transaction a reads transaction B the changed data that was committed.
    3. Phantom read: Transaction a reads transaction B has been committed of new data.

The first article is resolutely resisted, and the latter two are not considered in most cases.

That's why you have to have a transaction isolation level this thing, it's like a wall, isolating different transactions. By looking at the table below, you'll see how the different transaction isolation levels can handle transactional concurrency issues:

Transaction ISOLATION level dirty read non-repeatable read Phantom read
read_uncommitted
allow allow allow
read_committed
allow allow
repeatable_read
no allow
SERIALIZABLE
Span style= "color: #e53333;" > no no


Depending on your actual needs, it should be no longer difficult to refer to this table and finalize the transaction isolation level.

JDBC also provides these four types of transaction isolation levels, but the default transaction isolation level is not the same for different database products. The default transaction isolation level for our well-known MySQL database is read_committed,oracle, SQL Server, DB2, and so on have their own default values. I think read_committed has been able to solve most of the problems, the other on the specific situation specific analysis.

If the default transaction isolation level for other databases is not clear, you can use the following code to obtain:

?
12 DatabaseMetaData meta = DBUtil.getDataSource().getConnection().getMetaData();intdefaultIsolation = meta.getDefaultTransactionIsolation();

Tip: You can view all the isolation levels in the Java.sql.Connection class.

We know that JDBC is just a bridge between the Java program and the database, so how does the database isolate the transaction? In fact, it is the "lock" this thing. When inserting data, the table is locked, which is called the "lock table"; When the data is updated, the row is locked, which is called "Lock line." Of course this is beyond the scope of our discussion today, so let's leave some room for our DBA, lest he have nothing to write about.

In addition to the transaction isolation level provided by JDBC, what are some of the solutions that can improve transaction management capabilities?

Take a look at Spring's solution, which is actually a complement or extension to JDBC. It provides a very important function: Transaction propagation behavior (Transaction propagation Behavior).

Really good enough, Spring suddenly provides 7 kinds of transaction propagation behavior, these 7 kinds of behavior appeared, really is bright blind my dog eye!

  1. propagation_required
  2. rropagation_requires_new
  3. propagation_nested
  4. propagation_supports
  5. propagation_not_supported
  6. propagation_never
  7. propagation_mandatory

After reading the Spring reference manual, even more dizzy, what in the end is doing?

The first thing to be clear is, where does the transaction come from? Spread to where? The answer is to propagate from method A to method B. Spring solves only the transactional propagation between methods, and that's a lot of things, like:

    1. method A has a transaction, and method B has a transaction.
    2. method A has a transaction, and method B does not have a transaction.
    3. method A does not have a transaction, and method B has a transaction.
    4. method A does not have a transaction, and method B does not have a transaction.

This is 4 species, and there are 3 special cases. Or use my Style to do an analysis for everyone:

Assuming that the transaction is propagated from method A to method B, you need to face method B and ask yourself a question:

Does method A have a transaction?

  1. if not, create a new transaction and, if so, join the current transaction. This is propagation_required, which is also the default transaction propagation behavior provided by Spring, and is suitable for most situations.
  2. if not, a new transaction is created and, if so, the current transaction is suspended. This is rropagation_requires_new, which means creating a new transaction that has nothing to do with the original transaction.
  3. if not, create a new transaction and, if there is one, nest other transactions in the current transaction. This is propagation_nested, the legendary "nested transaction", where the nested child transactions are associated with the primary transaction (when the primary transaction commits or rolls back, the child transaction is committed or rolled back).
  4. if not, it is executed in a non-transactional manner, and if so, the current transaction is used. This is propagation_supports, this way very casual, there is no, there is, a little indifferent attitude, anyway I am supportive of you.
  5. if not, it is executed in a non-transactional manner, and if so, suspends the current transaction. This is propagation_not_supported, this way very tough, no no, there is I do not support you, hang you up, do not bird you.
  6. if not, it is executed in a non-transactional manner, and if so, throws an exception. This is propagation_never, this way is more fierce, there is no, there is an error, indeed enough cow, it said: I never support business!
  7. if not, an exception is thrown, and if so, the current transaction is used. This is propagation_mandatory, this way can be said to be a big bang, no business directly on the error, indeed enough ruthless, it said: I must have business!

See my above explanation, do the little friends feel that they are getting through the two veins of the governor? Read it a few times, and realize that it's your own thing.

It is important to note that propagation_nested is not deceived by its name, NESTED (nested), so when you call method B in similar method A, the transaction propagation behavior is used on method B, and if you do, you are wrong. Because you mistakenly think that propagation_nested is prepared for a method nesting call, the default propagation_required can help you do what you want to do.

Spring brings us transaction propagation behavior, which is really a very powerful and useful function. In addition, there are some small additional functions, such as:

    1. Transaction Timeout (Transaction timeout): in order to resolve the transaction time is too long, consume too many resources, so deliberately set a maximum transaction, if it is exceeded, roll back the transaction.
    2. Read-only transactions (Readonly Transaction): in order to ignore those methods that do not require transactions, such as reading data, this can effectively improve some performance.

Finally, we recommend that you use Spring's annotated transaction configuration instead of the XML-type transaction configuration. Because the annotations are so elegant, of course it all depends on your own situation.

Used in the Spring configuration file:

?
123 ...<tx:annotation-driven/>...

To use on a method that requires a transaction:

?
1234 @Transactionalpublicvoidxxx() {    ...}

Can be set in @Transactional annotations: Transaction isolation level, transaction propagation behavior, transaction time-out time, or read-only transaction.

Transaction propagation mechanism of isolation level and spring in spring transaction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.