春のプログラマティックトランザクション


1.mybatisのトランザクション制御

1. Mybatisト​​ランザクション:JDBC | Manageはデフォルトで自動的にコミットしません。
2. Spring統合mybatisト​​ランザクション:トランザクションはデフォルトで自動的に送信されます。
mybatis-spring-xxx.jarパッケージとspring-tx-xxxx.jarパッケージをインポートする必要があります
エッセンス:事務を春の管理に引き渡します

2.事務

1.事務

1.1。トランザクションの概念

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

1.2。トランザクション特性(ACID)

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

1.3。トランザクション3タイプの読み取りの問題

分離が考慮されていない場合、トランザクションは3種類の読み取り問題で構成されます

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

トランザクションは、同時操作における3種類の読み取りの問題を解決します:分離レベルを設定します。
同時アクセスが失われ、更新された問題:Java(ロック)/データベース(ロック)

1.4。トランザクション分離レベル

トランザクションの分離レベルをある程度設定すると、トランザクションの特性によって引き起こされる3種類の読み取りの問題を効果的に解決できます。

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

2.春のトランザクション管理

3層アーキテクチャ:Web層:Servlet / jsp ---->サービス層—> dao / mapper層
層状開発:ビジネスはサービス層にあります。

2.1。春はトランザクション管理APIを提供します

2.1.1.PlatformTransactionManager:プラットフォームトランザクションマネージャー。

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

2.1.2.TransactionDefinition:トランザクション定義

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

2.1.3.TransactionStatus:トランザクションステータス

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

2.1.4.3つの関係

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

2.2.APIの詳細な説明

        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实现来管理事务,在一个事务跨越多个资源时必须使用

第二に、春の取引の実現

1.マニュアル(プログラミング)業務(デモ理解)

インターフェイス:DataSourceTransactionManager
トランザクション管理テンプレートクラス:transactionTemplate

ステップ1:ビジネスレイヤーのどのメソッドがトランザクションを必要とするか(ハッカー)
UserInfoServiceImpl1.zz(int from、int to、int money); //銀行振込サービス

@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("转账失败");// 产生一个异常
            }
        
    }

}

インターフェイスIUserInfoService

package com.cc.service;

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

ステップ2:xmlでトランザクションマネージャーを構成します(ormフレームワークごとにトランザクション管理方法が異なります)
(ormフレームワーク: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>

ステップ3:ビジネスクラスでTransatcionTemplateトランザクションテンプレートクラス
new TransatcionTemplate(トランザクションマネージャー)を定義します。

ステップ4:トランザクション管理を必要とするメソッド
(最初のファイルUserInfoServiceImpl1のコード)

                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
    

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

ステップ5:テストし、ビジネスクラスのメソッドを呼び出します

@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.宣言事項(開発)(継続)

おすすめ

転載: blog.csdn.net/GanYangBa/article/details/108876779