上一章咱們簡單的介紹了swagger相關的實現,畢竟我都是直接貼代碼了,確實也是挺簡單的,哈哈哈。 這一章咱們主要介紹在springboot中的事務控制。java
本項目的GitHub:https://github.com/pc859107393/Go2SpringBoot.gitgit
有興趣交流springboot進行快速開發的同窗能夠加一下下面的企鵝羣。github
在傳統的Spring項目中,咱們經典三層中主要在service層進行事務控制,常見的配置是什麼呢?具體實現如圖3.1所示。spring
圖3.1 傳統Spring項目的事務控制數據庫
在傳統的Spring項目中,咱們的事務控制須要考慮以下幾點:express
既然咱們知道了傳統的事務控制咱們須要作的事情,理解了這一點,咱們也就能夠在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這個用戶信息存在,因此咱們事務控制成功了。具體效果不用上圖了,你們都能在各自的數據庫工具中看到。