Features/concepts of transactions

Transactions: a group of operations that either all succeed or fail;
Four key properties of a transaction (ACID):
  • Atomicity: “atom” means “indivisible”. The atomicity of a transaction refers to the fact that multiple operations involved in a transaction are logically indispensable. The atomicity of a transaction requires that all operations in a transaction either execute or none of them.
  • Consistency: Consistency refers to data consistency. In particular, all data is in a consistent state that meets service rules. The consistency principle requires that no matter how many operations are involved in a transaction, the data must be correct before and after the transaction. If one or more operations fail during a transaction, all other operations must be undone to restore the data to the state before the transaction was executed. This is called rollback.
  • Isolation: During the actual operation of an application, transactions tend to execute concurrently, so it is likely that many transactions will process the same data at the same time, so each transaction should be isolated from others to prevent data corruption. The principle of isolation requires that multiple transactions execute concurrently without interfering with each other.
  • Durability: Durability requires that modifications to data persist permanently after transactions complete, unaffected by system errors or other contingencies. Normally, changes made by transactions to data should be written to persistent storage.

The jar package

C3p0-0.9.1.2. Jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
Commons logging – 1.1.3. Jar
Mysql connector – Java – 5.1.7 – bin. The jar
Spring aop — 4.0.0. RELEASE. The jar
Spring – aspects – 4.0.0. RELEASE. The jar
Spring beans – 4.0.0. RELEASE. The jar
Spring – the context – 4.0.0. RELEASE. The jar
Spring – the core – 4.0.0. RELEASE. The jar
Spring – expression – 4.0.0. RELEASE. The jar
Spring – JDBC – 4.0.0. RELEASE. The jar
Spring – the orm – 4.0.0. RELEASE. The jar
Spring – tx – 4.0.0. RELEASE. The jar
 
Basic configuration:
<! --1. Configure a connection pool-->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"></property>
        <property name="password" value= "123456"></property>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/tx"></property>
    </bean>
<! --2. Add, delete, change and check JdbcTemplate of the database-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
<! --Configure transaction facets; Control the connection pool-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
    
<! --Enable annotation-based transactions. Depends on the TX namespace transaction-manager: specifies which transaction manager is-->
    <tx:annotation-driven/>Copy the code

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

/ * *Public int getPrice(String isbn); public int getPrice(String isbn); [2] Public void updateStock(String isbn); [3] Public void updateBalance(int price,String user); *@authorlfy ** /
@Repository
public classBookDao { @Autowired JdbcTemplate jdbcTemplate;/ * *Public int getPrice(String isbn); public int getPrice(String isbn); * Operation: book* /
    public intgetPrice(String isbn){ String sql= "select price from book where isbn=?"; Integer price= jdbcTemplate.queryForObject(sql, Integer.class, isbn);
        returnprice; };/ * *Public void updateStock(String isbn); public void updateStock(String isbn); * Action: book_stock* /
    public voidupdateStock(String isbn){ String sql= "UPDATE book_stock SET stock=stock-1 WHERE isbn=?"; jdbcTemplate.update(sql, isbn); }/ * *Public void updateBalance(int price,String user); public void updateBalance(int price,String user); * Reduce the balance of the user; Account * String user: user name to reduce the balance * int price: how much to reduce (the amount reduced is the book price)* /
    public void updateBalance(intprice,String user){ String sql= "update account set balance = balance-? where username=?"; jdbcTemplate.update(sql, price,user); }public voidupdatePrice(String isbn){ String sql= "update book set price = 999 WHERE isbn=?"; jdbcTemplate.update(sql, isbn); }}Copy the code

Transaction annotations are primarily added to the Service layer to implement transaction operations using Aop:

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

importcom.atguigu.dao.BookDao; @Servicepublic classBookService { @Autowired BookDao bookDao; @Transactional(noRollbackFor=ArithmeticException.class, timeout=3,propagation=Propagation.REQUIRES_NEW)
    public void checkout(String username,String isbn){
        //Find out book prices
        int price = bookDao.getPrice(isbn);
        //1. Deduct the balance of users
        bookDao.updateBalance(price, username);
        //Reduce the inventory of books
        bookDao.updateStock(isbn);
        
        //Thread.sleep(3000);
        //new FileInputStream("D://ahahahah//aa.txt");System.out.println(" Checkout complete...."); } @Transactional(propagation=Propagation.REQUIRED,timeout=3)
    public void updatePrice(String isbn){
        try{ Thread.sleep(3000); }catch(InterruptedException e) { e.printStackTrace(); } bookDao.updatePrice(isbn); }}Copy the code

Spring transaction manager

Properties of transaction control:

Propagation: the propagation of transactions; We can specify the relationship between large and small transactions through control;

Propagation (in the case of a shared transaction, the property configuration of a large transaction is propagated to a small transaction)+ behavior (whether or not a shared transaction is shared).

Isolation: The isolation level of a transaction, isolating individual transactions;
The isolation = isolation. READ_UNCOMMITTED;
According to actual business logic;
The following problems may occur if transactions are not applicable:
  1. Dirty read: Data is rolled back before it is committed during the same transaction.
  2. Non-repeatable read: Data is read differently for multiple times during the same transaction.
  3. Phantom read: During the same transaction, data is read several times and records are found to be fewer or more.

Essentially one reads again and one revises;

The database system must have the ability to isolate the individual transactions running concurrently so that they do not interfere with each other and avoid various concurrency problems. The degree to which a transaction is isolated from other transactions is called the isolation level. The SQL standard defines multiple transaction isolation levels, which correspond to different interference levels. The higher the isolation level, the better the data consistency, but the weaker the concurrency.

① READ UNCOMMITTED: READ UNCOMMITTED

Allow Transaction01 to read uncommitted changes in Transaction02.

② READ COMMITTED

Requires Transaction01 to read only changes that Transaction02 has committed.

REPEATABLE READ

Ensure that Transaction01 can read the same value from a field multiple times, that is, prohibit other transactions from updating the field while Transaction01 is executing.

④ Serialization: SERIALIZABLE

Ensure that Transaction01 can read the same row from a table multiple times, and prohibit other transactions from adding, updating, or deleting the table while Transaction01 is executing. Can avoid any concurrency problems, but performance is very poor.

(5) The ability of each isolation level to solve concurrency problems is shown in the following table

 

⑥ Support for transaction isolation level by various database products

 

Specify the transaction isolation level in Spring

annotations

When you use the @Transactional annotation to declaratively manage transactions, you can set the isolation level in the isolation attribute of @Transactional

XML

In Spring 2.x transaction notifications, you can specify the isolation level in the <tx: Method > element

An exception that triggers a transaction rollback

The default

It is rolled back when a RuntimeException or Error is caught, but not when a compile-time exception is caught.

Settings via

annotations

@ Transactional annotation

  1. RollbackFor property: Specifies the type of exception that must be rolled back when encountered
  2. NoRollbackFor attribute: Specifies the type of exception that will not be rolled back when encountered

 

XML

In Spring 2.x transaction notifications, you can specify rollback rules in the <tx:method> element. If there is more than one exception, separate it with a comma.

Timeout and read-only properties of the transaction

Introduction to the

Because transactions can acquire locks on rows and tables, long transactions consume resources and have an impact on overall performance.

If a transaction only reads data but does not modify it, the database engine can optimize the transaction.

Timeout transaction attribute: How long a transaction can remain in place before forced rollback. This prevents long running transactions from hogging resources.

Read-only transaction property: Indicates that the transaction reads data but does not update data, which helps the database engine optimize the transaction.

Set up the

annotations

@ Transaction annotations

XML

In Spring 2.x transaction notifications, timeout and read-only attributes can be specified in the <tx:method> element

For a more complete XML configuration:

<?The XML version = "1.0" encoding = "utf-8"? >
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <context:component-scan base-package="com.atguigu"></context:component-scan>
    
    <! --1. Configure a connection pool-->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"></property>
        <property name="password" value= "123456"></property>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/tx"></property>
    </bean>
    
    <! --2. Add, delete, change and check JdbcTemplate of the database-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
    
    <! --3. Configure transaction facets. Control the connection pool-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>
    
    <! --4. Enable annotation-based transactions. Depends on the TX namespace transaction-manager: specifies which transaction manager is-->
    <! -- <tx:annotation-driven/> -->
    
    <! --Xml-based transaction configuration; Aop and TX namespaces are required-->
    <! --TransactionManager transaction facets-->
    <aop:config>
        <! --Specifies which methods the transaction manager should access for transaction control-->
        <aop:pointcut expression="execution(* com.soyoungboy.service.*.*(..) )" id="txPoint"/>
        <! --Aop :advisor: Pointcut-ref: Cuts into a transaction using the specified pointcut expression-->
        <aop:advisor advice-ref="myTxAdvice" pointcut-ref="txPoint"/>
    </aop:config>
    
    <! --Use tx namespaces and configurations (transaction recommendations, transaction attributes, transaction enhancement); Id ="myTxAdvice" : < AOP :advisor advice-ref="myTxAdvice" transaction-manager="transactionManager": specify which transaction manager to configure-->
    <tx:advice id="myTxAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <! --Specify transaction methods: represents that all methods are transaction methods-->
            <tx:method name= "*"/>
            <tx:method name="checkout" rollback-for="java.lang.Exception"/>
            <tx:method name="updatePrice" propagation="REQUIRES_NEW"/>
            <! --Those that begin with GET are optimized by reading only-->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    
    <! --Transaction control based on XML configuration is a bit more-->


</beans>Copy the code