SpringBoot2-第三章:springboot的事務控制

上一章咱們簡單的介紹了swagger相關的實現,畢竟我都是直接貼代碼了,確實也是挺簡單的,哈哈哈。 這一章咱們主要介紹在springboot中的事務控制。java

本項目的GitHub:https://github.com/pc859107393/Go2SpringBoot.gitgit

有興趣交流springboot進行快速開發的同窗能夠加一下下面的企鵝羣。github

行走的java全棧

回顧事務控制

在傳統的Spring項目中,咱們經典三層中主要在service層進行事務控制,常見的配置是什麼呢?具體實現如圖3.1所示。spring

圖3.1

圖3.1 傳統Spring項目的事務控制數據庫

在傳統的Spring項目中,咱們的事務控制須要考慮以下幾點:express

  • 開啓事務管理
  • 區別只讀事務和讀寫事務
  • 配置Spring事務控制規則
  • 找到service層的實現類

既然咱們知道了傳統的事務控制咱們須要作的事情,理解了這一點,咱們也就能夠在springboot項目中推測咱們須要哪些東西。 ①. 事務控制相關依賴資源 ②. 事務管理開啓 ③.事務讀寫規則控制 ④.事務讀寫的實現.springboot

在前面咱們構建項目的時候已經加入了spring-boot-starter-aop,因此依賴資源不是問題。接着咱們須要編寫代碼來實現相關的規則、開啓事務和實現事務。app

首先咱們能夠上網查詢一下springboot相關的事務,無外乎都是懶人辦法直接在service方法上面添加註解@Transactional和在入口類上面使用@EnableTransactionManagement,這樣就能在項目中指定的方法上面開啓事務了。spring-boot

可是有沒有一種更懶得方式呢?必定是有的,估計也是和Spring項目中相似。咱們檢驗的標準是什麼?確定是在service對應的方法內發生異常引發回滾操做。其餘的原理沒必要解釋太多,先上碼。工具

@SpringBootApplication
@EnableWebMvc
@EnableSwagger2
@MapperScan(value = ["cn.acheng1314.base.dao"])
@Configuration
@EnableTransactionManagement
class BaseApplication : WebMvcConfigurer {
    //事務類型參數
    fun transactionAttributeSource(): TransactionAttributeSource {
        val source = NameMatchTransactionAttributeSource()
        //只讀或可寫事務
        val readOnlyTx = RuleBasedTransactionAttribute()
        readOnlyTx.isReadOnly = true
        readOnlyTx.propagationBehavior = TransactionDefinition.PROPAGATION_SUPPORTS

        //可寫事務
        val requiredTx = RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED
                , Collections.singletonList(RollbackRuleAttribute(Exception::class.java)))

        val txMap = HashMap<String, TransactionAttribute>()
        txMap["add*"] = requiredTx
        txMap["save*"] = requiredTx
        txMap["insert*"] = requiredTx
        txMap["update*"] = requiredTx
        txMap["delete*"] = requiredTx
        txMap["get*"] = readOnlyTx
        txMap["query*"] = readOnlyTx
        txMap["find*"] = readOnlyTx
        source.setNameMap(txMap)
        return source
    }

    /*事務攔截器*/
    @Bean(value = ["txInterceptor"])
    fun getTransactionInterceptor(tx: PlatformTransactionManager): TransactionInterceptor {
        return TransactionInterceptor(tx, transactionAttributeSource())
    }

    /**切面攔截規則 參數會自動從容器中注入 */
    @Bean
    fun pointcutAdvisor(txInterceptor: TransactionInterceptor): AspectJExpressionPointcutAdvisor {
        val pointcutAdvisor = AspectJExpressionPointcutAdvisor()
        pointcutAdvisor.advice = txInterceptor
        pointcutAdvisor.expression = "execution (* cn.acheng1314.base.service.*ServiceImpl.*(..))"
        return pointcutAdvisor
    }

    //省略其餘代碼
}
複製代碼

在上面的事務規則參數中咱們設置了兩邊倒事務(readOnlyTx,使用了TransactionDefinition.PROPAGATION_SUPPORTS設置爲兩邊倒事務)和可寫入事務(requiredTx)。接着咱們在UserServiceImpl中寫一個發生異常的方法,測試是否可以產生事務回滾,代碼片斷以下:

// @Transactional
    @Throws(Exception::class)
    fun addUser() {
        val user = User()
        user.duty = "aaa"
        user.loginName = "aaa"
        user.name = "aaa"
        user.password = "aaa"
        user.createDate = Date()
        baseMapper.insert(user)
        throw Exception("測試事務")
    }
複製代碼

咱們來一點點代碼進行單元測試,以下:

@RunWith(SpringJUnit4ClassRunner::class)
@SpringBootTest(classes = [BaseApplication::class])
class UserServiceImplTest {
    @Autowired
    private lateinit var userService: UserServiceImpl

    @Test
    fun addUserTest() {
        userService.addUser()
    }
}
複製代碼

最後運行測試代碼後,咱們能夠發如今數據庫中並無aaa這個用戶信息存在,因此咱們事務控制成功了。具體效果不用上圖了,你們都能在各自的數據庫工具中看到。

相關文章
相關標籤/搜索