1-4 事務抽象 事務的傳播性與隔離性

Springboot有一致的事務模型

JDBC/Hibernate/myBatis

DataSource/JTA

事務抽象的核心接口

PlatformTransactionManager

    DataSourceTransationManager

    HibernateTransactionManager

    JtaTransactionManager

 

TransactionDefinition

    Propagation //傳播性

    Isolation //隔離性

    Timeout //超時

    Read-only status //是否只讀

 

事務的傳播特性(7種,文檔中只提了3項)
傳播性 描述
PROPAGATION_REQUIRED 0 當前有事務用當前的,沒有就用新的
PROPAGATION_SUPPORTS 1 事務可有可無,不是必須的
PROPAGATION_MANDATORY 2 當前一定要有事務,不然就拋異常
PROPAGATION_REQUIRES_NEW 3 無論是否有事務都起個新事務
PROPAGATION_NOT_SUPPORTED 4 不支持事務,按非事務方式運行
PROPAGATION_NEVER 5 不支持事務,如果有事務則拋異常
PROPAGATION_NESTED 6 當前有事務就在當前是事務裏再起一個事務

 

 

 

 

 

 

 

 

事務的隔離特性
隔離性 髒讀 不可重複讀 幻讀
ISOLATION_READ_UNCOMMITTER 1 T T T
ISOLATION_READ_COMMITTED 2 F T T
ISOLATION_REPEATABLE_READ 3 F F T
ISOLATION_SERIALIZABLE 4 F F F

 

 

 

 

 

 

 

編程式事務

TransactionTemplate

    TransactionCallback

    TransactionCallbackWithoutResult

PlatformTransactionManager

    可以傳入TransactionDefinition進行定義

 

通過編程式事務編寫

package com.example.ribi;

import com.example.ribi.example.User;
import com.example.ribi.mapper.UserRepository;
import com.example.ribi.service.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootApplication
@EnableCaching(proxyTargetClass = true)
@EnableTransactionManagement
@Slf4j
public class RibiApplication implements ApplicationRunner {

	public static void main(String[] args) {
		SpringApplication.run(RibiApplication.class, args);
	}

	@Autowired
    private JdbcTemplate jdbcTemplate;

	@Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public void run(ApplicationArguments args) throws Exception{
        log.info("0s count is {}",getCount()); //0s 一開始表裏有的記錄
        jdbcTemplate.execute("insert into user values (10,'aaa','bbb')");
        log.info("1s count is {}",getCount()); //1s 插入一條記錄後
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                jdbcTemplate.execute("insert into user values (11,'aaa','bbb')");
                log.info("2s count is {}",getCount()); //2s 開啓事務設置回滾,插入一條記錄再查詢
                status.setRollbackOnly();
            }
        });
        log.info("3s count is {}",getCount()); //3s 查詢事務回滾後的表記錄數
    }

    public Long getCount(){
        return (Long)jdbcTemplate.queryForList("select count(1) as CNT from user").get(0).get("CNT");
    }
}

運行結果

2019-05-21 17:57:24.745  INFO 48768 --- [main] com.example.ribi.RibiApplication : 0s count is 4 // 一開始4條
2019-05-21 17:57:24.786  INFO 48768 --- [main] com.example.ribi.RibiApplication : 1s count is 5 // 插入一條後變5條
2019-05-21 17:57:24.805  INFO 48768 --- [main] com.example.ribi.RibiApplication : 2s count is 6 // 開啓事務再插入一條查詢變成6條 然後再回滾
2019-05-21 17:57:24.820  INFO 48768 --- [main] com.example.ribi.RibiApplication : 3s count is 5 // 回滾後變成5條

註解:

Application類添加

@EnableTransactionManagement

註解在方法頭上添加

@Transactional

-- 部分摘自 極客時間 玩轉Spring全家桶 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章