什么是fescar?
關于fescar的詳細介紹,請參閱fescar wiki。
傳統的2pc提交協議,會持有一個全局性的鎖,所有局部事務預提交成功后一起提交,或有一個局部事務預提交失敗后一起回滾,最后釋放全局鎖。鎖持有的時間較長,會對并發造成較大的影響,死鎖的風險也較高。
fescar的創新之處在于,每個局部事務執行完立即提交,釋放本地鎖;它會去解析你代碼中的sql,從數據庫中獲得事務提交前的事務資源即數據,存放到undo_log中,全局事務協調器在回滾的時候直接使用undo_log中的數據覆蓋你提交的數據。
spring boot如何集成fescar?
我們可以從官方代碼庫中看到,fescar目前提供的示例是針對使用dubbo的服務,那spring boot的項目如何集成fescar呢?
和很多2pc提交協議(如tx_lcn)的解決方案一樣,fescar也是在數據源處做了代理,和事務協調器進行通信,來決定本地事務是否回滾。所以,第一步,在你的spring boot項目中,首先應使用fescar提供的代理數據源作為你的數據源,例如:
1
2
3
|
druiddatasource datasource = initdatasource(datasourceprops.get( "url" ).tostring(), datasourceprops.get( "username" ).tostring(), datasourceprops.get( "password" ).tostring()); datasourceproxy proxy = new datasourceproxy(datasource); |
然后,你需要創建一個feign攔截器,把rootcontext中的xid(xid用于標識一個局部事務屬于哪個全局事務,需要在調用鏈路的上下文中傳遞)傳遞到上層調用鏈路。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@component public class requestheaderinterceptor implements requestinterceptor { @override public void apply(requesttemplate template) { string xid = rootcontext.getxid(); if (stringutils.isnotblank(xid)){ template.header( "fescar-xid" ,xid); } } } |
最后,你需要創建一個http rest請求攔截器,用于把當前上下文中獲取到的xid放到rootcontext。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import com.alibaba.fescar.core.context.rootcontext; import org.apache.commons.lang.stringutils; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.web.filter.onceperrequestfilter; import javax.servlet.filterchain; import javax.servlet.servletexception; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import java.io.ioexception; public class fescarxidfilter extends onceperrequestfilter { protected logger logger = loggerfactory.getlogger(fescarxidfilter. class ); @override protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain) throws servletexception, ioexception { string xid = rootcontext.getxid(); string restxid = request.getheader( "fescar-xid" ); boolean bind = false ; if (stringutils.isblank(xid)&&stringutils.isnotblank(restxid)){ rootcontext.bind(restxid); bind = true ; if (logger.isdebugenabled()) { logger.debug( "bind[" + restxid + "] to rootcontext" ); } } try { filterchain.dofilter(request, response); } finally { if (bind) { string unbindxid = rootcontext.unbind(); if (logger.isdebugenabled()) { logger.debug( "unbind[" + unbindxid + "] from rootcontext" ); } if (!restxid.equalsignorecase(unbindxid)) { logger.warn( "xid in change during http rest from " + restxid + " to " + unbindxid); if (unbindxid != null ) { rootcontext.bind(unbindxid); logger.warn( "bind [" + unbindxid + "] back to rootcontext" ); } } } } } } |
這樣就完成了fescar的集成。
開始使用吧!
首先在項目中初始化兩個bean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@bean public fescarxidfilter fescarxidfilter(){ return new fescarxidfilter(); } @bean public globaltransactionscanner scanner(){ globaltransactionscanner scanner = new globaltransactionscanner( "fescar-test" , "my_test_tx_group" ); return scanner; } |
然后寫兩個服務,服務a調用服務b,并在a服務的調用方法上打上@globaltransactional標簽:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@globaltransactional (timeoutmills = 300000 , name = "fescar-test-tx" ) public void testfescar() throws businessexception { dictionvo dictionvo = new dictionvo(); dictionvo.setcode( "simidatest" ); dictionvo.setvalue( "1" ); dictionvo.setdesc( "simidatest" ); dictionvo.setappid( "sso" ); commonservice.creatediction(dictionvo); //遠程調用服務b areamapper.deleteareabysysno( 2 ); //本地事務 throw new businessexception( "主動報錯" ); } |
最后,兩個項目中添加application.conf文件,用于告訴客戶端如何與分布式協調器通信,官方示例中有這個文件,就不在此貼代碼啦,application.conf傳送門
啟動事務協調器,sh fescar-server.sh 8091 ~/dksl/git/fescar/data,啟動你的項目,開始測試吧!
last thing
分布式事務作為微服務應用中的老大難問題,在現有的解決方案中,個人認為fescar是目前最輕量并且代價最小的一種解決方案。目前的版本,事務協調器還不能分布式部署,官方給出的路線圖是在三月底會有第一個生產可用版本。讓我們一起參與到fescar的社區中,共同推動fescar生態建設,讓落地微服務不必再擔心分布式事務的問題。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/DKSL/p/fescar.html