Programmatic transactions in spring


1. Transaction control of mybatis

1. Mybatis transaction: JDBC|Manage will not automatically commit by default.
2. Spring integrated mybatis transaction: the transaction is automatically submitted by default.
Need to import mybatis-spring-xxx.jar package and spring-tx-xxxx.jar package
Essence: hand over the affairs to spring management

2. Affairs

1. Affairs

1.1. Transaction concept

		事务:是逻辑上一组操作,要么全都成功,要么全都失败.
		事物目的就是解决【数据不一致】的问题。

1.2. Transaction characteristics (ACID)

		原子性:(A)事务不可分割
        一致性(C):事务执行的前后,数据完整性保持一致.
        隔离性(I):一个事务执行的时候,不应该受到其他事务的打扰
        持久性(D):一旦结束,数据就永久的保存到数据库

1.3. Transaction 3 types of reading problems

If isolation is not considered, the transaction consists of three types of read problems

		脏读:一个事务读到另一个事务未提交数据
		不可重复读:一个事务读到另一个事务已经提交数据(update)导致一个事务多次查询结果不一致
		虚读:一个事务读到另一个事务已经提交数据(insert)导致一个事务多次查询结果不一致

Transaction solves 3 types of read problems in concurrent operations: set the isolation level.
Concurrent access is lost and updated problems: Java (lock)/database (lock)

1.4. The isolation level of the transaction

Set the isolation level of the transaction, to some extent, it can effectively solve the three types of read problems caused by the transaction characteristics

        未提交读:   以上情况都有可能发生。
        已提交读:   避免脏读,但不可重复读,虚读是有可能发生。
        可重复读:   避免脏读,不可重复读,但是虚读有可能发生。
        串行的:        避免以上所有情况.    系统吞吐量很低

2. Transaction management in Spring

Three-tier architecture: web layer: Servlet/jsp---->service layer—>dao/mapper layer
Layered development: business is in the Service layer.

2.1.Spring provides transaction management API

2.1.1.PlatformTransactionManager: Platform transaction manager.

            commit(TransactionStatus status) 
            getTransaction(TransactionDefinition definition) 
            rollback(TransactionStatus status) 

2.1.2.TransactionDefinition: Transaction Definition

            ISOLation_XXX:                事务隔离级别.
            PROPAGATION_XXX:    事务的传播行为.(不是JDBC中有的,为了解决实际开发问题.)
            Timeout:                              过期时间

2.1.3.TransactionStatus: Transaction status

        是否有保存点
        是否一个新的事务
        事务是否已经提交

2.1.4. Relationship of the three

        PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,
        管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.

2.2.API detailed explanation

        Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现
        org.springframework.jdbc.datasource.DataSourceTransactionManager    
        使用Spring JDBC或iBatis 进行持久化数据时使用

        org.springframework.orm.hibernate3.HibernateTransactionManager  
        使用Hibernate3.0版本进行持久化数据时使用
        
        org.springframework.orm.jpa.JpaTransactionManager           
        使用JPA进行持久化时使用
        
        org.springframework.jdo.JdoTransactionManager   
         当持久化机制是Jdo时使用
        
        org.springframework.transaction.jta.JtaTransactionManager
          使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用

Second, the realization of spring transactions

1. Manual (programming) affairs (demo understanding)

Interface: DataSourceTransactionManager
transaction management template class: transactionTemplate

Step 1: Which methods of the business layer require transactions (hacking)
UserInfoServiceImpl1.zz(int from ,int to ,int money);//Bank transfer service

@Component
public  class UserInfoServiceImpl1 implements IUserInfoService {
    
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Autowired
    private  TransactionTemplate transactionTemplate;
    
//    @Autowired
//    public UserInfoServiceImpl1(PlatformTransactionManager transactionManager) {
    
    
//        this.transactionTemplate = new TransactionTemplate(transactionManager);
//    }

    /**
     * 转账业务:旺财(from)转账给来福(to),转money钱
     * 
     * 旺财(from) 更新操作 减money 来福 (to) 更新操作 加money money =200
     * 
     * 
     * zz(1,2,300)
     */

    @Override
    public void zz(int from, int to, int money) {
    
    
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
    

            protected void doInTransactionWithoutResult(TransactionStatus status) {
    
    
                try {
    
    
                    //转账的操作
                    zzOptional(from, to, money);
                    System.out.println("转账成功");
                } catch (Exception ex) {
    
    
                    System.out.println("转账失败,进行回滚");
                    status.setRollbackOnly();
                }
            }
        });
    }

    private void zzOptional(int from, int to, int money)  throws Exception{
    
    
        
            // 一,==============旺财的钱减少300==============
            // 1.1查询旺财有多少钱
            UserInfo wc = userInfoMapper.selectByPrimaryKey(from);
            System.out.println(wc);
            // 1.2扣旺财有300
            wc.setMoney(wc.getMoney() - money);
            int result = userInfoMapper.updateByPrimaryKey(wc);

            // ==============二,来福的钱增加300==============
            // 1.1查询旺财有多少钱
            UserInfo lf = userInfoMapper.selectByPrimaryKey(to);
            System.out.println(lf);
            // 1.2扣旺财有300
            lf.setMoney(lf.getMoney() + money);
            int result2 = userInfoMapper.updateByPrimaryKey(lf);
            
            //==============最后的结果==============
            if (result > 0 && result2 > 0) {
    
    
                System.out.println("转账成功!!");
            } else {
    
    
                // int a = 10/0;//产生一个异常
                throw new Exception("转账失败");// 产生一个异常
            }
        
    }

}

Interface IUserInfoService

package com.cc.service;

public interface IUserInfoService {
    
    
    /*
     * from:转出的账户
     * to:转入的账户
     * money:转的金额
     * 
     */
    public void zz(int from ,int to,int money);
}

Step 2: Configure the transaction manager in xml (different orm frameworks have different transaction management methods)
(orm framework: mybatis, hibernate, jpa, jdbcTemplate...)
create spring-datasource.xml

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
	<!--1、加载数据库的配置文件  -->
	<context:property-placeholder location="database.properties"/>
	<!-- 2、创建数据源对象实例-->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	   <property name="driverClassName"  value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${userName}" />
        <property name="password" value="${password}" />
	</bean>
	<!-- 3、创建sqlSessionFactory实例 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	   <!--1.dataSource -->
	   <property name="dataSource" ref="dataSource"></property>
	   <!-- 2.xml配置文件位置-->
	   <property name="mapperLocations" value="classpath:mapper/*.xml"/>
	   <!-- 3.别名-->
	   <!-- 4.驼峰自定映射 -->
	</bean>
	<!-- 4、指定mapper接口的位置 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	   <property name="basePackage" value="com.cc.mapper"></property>
	</bean>
	
	<!--  开启注解配置-->
	<context:annotation-config/>
	<context:component-scan base-package="com.cc"></context:component-scan>
	
	<!--5、spring针对MyBaits的事务管理器  -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	   <property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!--6、手动事务模板  -->
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> 
	   <property name="transactionManager" ref="transactionManager"></property>
	</bean>  
</beans>

Step 3: Define the TransatcionTemplate transaction template class
new TransatcionTemplate (transaction manager) in the business class ;

Step 4: In the method that requires transaction management
(the code in the first file UserInfoServiceImpl1:)

                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
    

                protected void doInTransactionWithoutResult(TransactionStatus status) {
    
    
                    try {
    
    
                        updateOperation1();//持久层操作1   扣二狗子的300
                        updateOperation2();//持久层操作2   增加付自强300
                    } catch (SomeBusinessException ex) {
    
    
                        status.setRollbackOnly();
                    }
                }
            });

Step 5: Test, call the method of the business class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-datasource.xml")
public class MyBatisSpringTest {
    
    
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Autowired
    private UserInfoServiceImpl1 UserInfoServiceImpl1;
    
    @Test
    public void whenSelectSuccess() {
    
    
        System.out.println(userInfoMapper.selectByExample(null));
    }
    
    @Test
    public void whenZzSuccess() {
    
    
        UserInfoServiceImpl1.zz(1, 2,100);
    }

}

2. Declarative affairs (development) (to be continued)

Guess you like

Origin blog.csdn.net/GanYangBa/article/details/108876779