今天同事遇到乙個問題:在使用spring的事務管理時,開啟了乙個事務,接著在內部開啟了兩個傳播模式為嵌入(propagation_nested)的事務,想看下這三個事務的id是否一致,但是查了半天也沒查到spring怎麼獲取事務id。
這裡提供兩個思路,不知到對不對。
既然spring的事務最終還是要看mysql,那我們不如直接去mysql裡查詢事務id:
select trx_id
from information_schema.innodb_trx
where trx_mysql_thread_id = connection_id();
select trx_id
from information_schema.innodb_trx
where trx_mysql_thread_id = connection_id();
在主事務方法上新增註解:@transactional
在子事務方法上新增 :@transactional(propagation = propagation.nested)
在方法中呼叫獲取事務id的方法並列印出來:
############## main transaction id is: 283244068130304.
############## sub nested transaction id is: 283244068130304.
查詢資料庫:
這裡可能存在的問題:因為這個查詢使用connection_id作為條件,還沒搞明白這個連線id怎麼來的,原理還有點含糊,不建議用這種方法。
使用:transactionsynchronizationmanager.getcurrenttransactionname()
獲取事務名,名稱是加了事務註解的方法的「包名+方法名」的全路徑名稱。
目前來看這種方法更靠譜。
string txname = transactionsynchronizationmanager.getcurrenttransactionname();
logconstant.bus.info("\n ############## main transaction name is: {}.", txname);
檢視原始碼,是儲存了乙個threadlocal變數:
private static final threadlocalcurrenttransactionname =
new namedthreadlocal("current transaction name");
spring的事務管理會在開啟事務時往裡塞值。
測試一下:
定義事務註解:
@target()
@retention(retentionpolicy.runtime)
@transactional(rollbackfor = )
@documented
public @inte***ce runintransactional
開啟外層事務:
/**
* @description 測試事務id
* @author lilong
* @date 2019-03-11 16:19
*/@service
public class testtransactional .", txname);
testtransactionalpropagation.testnested();
testtransactionalpropagation.testrequired();
testtransactionalpropagation.testrequiresnew();}}
在上面方法的內部開啟事務(注意在新的類檔案裡寫下面兩個方法,不要跟上面的方法在同乙個類裡,否則事務註解會失效):
/**
* @description 測試事務傳播機制
* @author lilong
* @date 2019-03-11 10:13
*/@service
public class testtransactionalpropagation .", txname);
}/**
* required
*/@runintransactional(propagation = propagation.required)
public void testrequired() .", txname);
}/**
* requires_new
*/@runintransactional(propagation = propagation.requires_new)
public void testrequiresnew() .", txname);}}
列印結果:
############ main transaction name is:service.impl.testtransactional.testtransactionalname.
############## sub testnested transaction name is: service.impl.testtransactional.testtransactionalname.
############## sub testrequired transaction name is: service.impl.testtransactional.testtransactionalname.
############## sub testrequiresnew transaction name is: service.impl.testtransactionalpropagation.testrequiresnew.
這個方法我這邊是好的,同事那邊取到的事務名是null,暫時還沒搞懂原因,估摸著是spring的事務框架在啟動事務時往這個threadlocal變數裡塞值了,我這邊是用註解宣告的方式使用的事務,同事那邊用的是程式設計的方式,可能還是有差別,有時間再好好研究下。 Spring 事務 事務控制
0 註解 autowire 自動注入 url url b 1 spring專案中事務手動回滾 b transactionaspectsupport.currenttransactionstatus setrollbackonly 或者丟擲異常 transactional rollbackfor pu...
Spring事務(一) Spring事務的使用
事務的經典舉例 某人要在商店使用電子貨幣購買100元的東西,當中至少包括兩個操作 該人賬戶減少100元 商店賬戶增加100元 事務就是要確保以上兩個操作 都能完成 或者 一起取消,否則就會出現100元平白消失或出現的情況。摘自wiki spring事務有兩種方式 程式設計式事務管理 宣告式事務管理 ...
Spring事務(二) Spring事務的特點
實現事務必須滿足以下四大特性 隔離性 通過mvvc實現 相對應的有mvcc 原子性 一致性 永續性 通過資料庫的redo log undo log force log at commit實現 資料庫是可以控制事務的傳播和隔離級別的,spring在之上又進一步做了封裝,本質上是同一概念。事務的四大特性...