久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Spring事務(wù)失效的7個(gè)坑與底層原理:從JDBC到分布式事務(wù)

Spring事務(wù)失效的7個(gè)坑與底層原理:從JDBC到分布式事務(wù) 1. 事務(wù)失效的七宗罪我踩過的坑你大概率也會(huì)踩先講個(gè)真實(shí)事故。幾年前我維護(hù)過一個(gè)電商訂單系統(tǒng)線上出了一個(gè)詭異的bug用戶支付成功后訂單狀態(tài)正常更新但庫存卻莫名其妙多扣了一次。代碼看起來完全沒問題——service方法上明明白白標(biāo)著Transactional數(shù)據(jù)庫也確認(rèn)是InnoDB。查了兩天才定位到根因同一個(gè)類里方法A調(diào)用方法BB的事務(wù)注解根本沒生效。這就是Spring事務(wù)最經(jīng)典的坑之一自調(diào)用繞過代理。Transactional依賴AOP代理生效而Spring的代理機(jī)制決定了一個(gè)類內(nèi)部的方法調(diào)用是不會(huì)經(jīng)過代理對(duì)象的。this.orderService.update()拿到的這個(gè)this根本不是Spring容器里那個(gè)被代理過的bean而是原始對(duì)象。原始對(duì)象上的注解Spring根本看不見。結(jié)果就是你以為開啟了事務(wù)實(shí)際上沒有。庫存扣減在無事務(wù)狀態(tài)下執(zhí)行訂單那邊一旦報(bào)錯(cuò)回滾庫存早就提交了。1.1 自調(diào)用問題最隱蔽的事務(wù)殺手自調(diào)用這個(gè)坑的隱蔽之處在于它不會(huì)報(bào)錯(cuò)不會(huì)警告日志里什么都看不出來只有數(shù)據(jù)對(duì)不上賬的時(shí)候才會(huì)暴露。Service public class OrderService { Transactional public void createOrder(OrderDTO dto) { // 扣庫存 stockService.deduct(dto.getSkuId(), dto.getQuantity()); // 插入訂單 orderMapper.insert(buildOrder(dto)); // 這里調(diào)用了自身方法事務(wù)注解失效 this.sendNotification(dto); } Transactional(propagation Propagation.REQUIRES_NEW) public void sendNotification(OrderDTO dto) { // 通知邏輯 } }上面這段代碼里sendNotification的REQUIRES_NEW完全無效。因?yàn)閠his.sendNotification()走的是原始對(duì)象不是代理。解決辦法有三個(gè)把需要事務(wù)的方法挪到另一個(gè)Service類——最推薦職責(zé)也最清晰。注入自身代理Autowired private OrderService self;然后調(diào)用self.sendNotification()。使用AopContext.currentProxy()需要開啟EnableAspectJAutoProxy(exposeProxy true)然后((OrderService) AopContext.currentProxy()).sendNotification()。方案2最實(shí)用但要注意循環(huán)依賴問題——Spring 4.3之后字段注入的循環(huán)依賴是允許的但構(gòu)造器注入就不行。方案3代碼看著別扭但確實(shí)有效。1.2 非public方法注解白寫了Transactional用在private或者protected方法上Spring容器啟動(dòng)時(shí)根本不報(bào)錯(cuò)但方法執(zhí)行時(shí)事務(wù)就是沒開。原理不復(fù)雜Spring AOP生成代理的時(shí)候JDK動(dòng)態(tài)代理基于接口只代理public方法CGLIB雖然能代理非public方法但Spring官方明確說了Transactional只支持public方法。最騷的是如果你把Transactional放在public方法上、但里面調(diào)用了private方法private方法里的事務(wù)注解同樣無效——因?yàn)槭聞?wù)邊界已經(jīng)在public方法的代理上確定了內(nèi)層調(diào)用不會(huì)再開啟新事務(wù)除非傳播行為是REQUIRES_NEW。我見過不少項(xiàng)目把Transactional加到private方法上然后一臉疑惑地說為什么回滾了沒生效。排查方法很簡(jiǎn)單看日志里有沒有TransactionInterceptor的getTransaction記錄沒有就是代理沒走。1.3 異常被吞回滾了個(gè)寂寞這是最常見也最無語的一種。Java的檢查型異常checked exception默認(rèn)不會(huì)觸發(fā)Spring事務(wù)回滾但很多人不知道這一點(diǎn)隨手寫了個(gè)throws Exception然后事務(wù)就失效了。Transactional public void transfer(Account from, Account to, BigDecimal amount) throws Exception { accountMapper.decrease(from.getId(), amount); accountMapper.increase(to.getId(), amount); // 業(yè)務(wù)校驗(yàn)不通過拋了個(gè)業(yè)務(wù)異常 throw new BizException(余額不足); }BizException如果是繼承Exception而不是RuntimeException上面這個(gè)事務(wù)不會(huì)回滾錢就憑空消失了。Spring的默認(rèn)回滾策略是只回滾RuntimeException和Error。檢查型異常如IOException不會(huì)觸發(fā)回滾因?yàn)镾pring認(rèn)為你既然顯式聲明了這個(gè)異常說明你可以處理它事務(wù)繼續(xù)提交是合理的。解決方案兩個(gè)方向業(yè)務(wù)異常統(tǒng)一繼承RuntimeException——大多數(shù)項(xiàng)目的做法最簡(jiǎn)單。在Transactional上顯式指定Transactional(rollbackFor Exception.class)——最穩(wěn)一勞永逸。我個(gè)人的習(xí)慣是兩者都做自定義業(yè)務(wù)異常繼承RuntimeException同時(shí)在Transactional上寫rollbackFor Exception.class。雖然看起來冗余但團(tuán)隊(duì)里總有人會(huì)寫檢查型異常。1.4 多線程子線程異常主線程事務(wù)照樣提交Transactional的事務(wù)上下文存在ThreadLocal里子線程拿不到父線程的事務(wù)上下文。Transactional public void batchProcess(ListOrder orders) { orders.parallelStream().forEach(order - { // 這里拋異常父線程事務(wù)不會(huì)感知 processOne(order); }); }如果一定要在多線程里用事務(wù)只能每個(gè)線程自己開事務(wù)用TransactionTemplate包住子線程的任務(wù)代碼然后在線程池層面做異常聚合——子線程里有任何失敗主線程如何決定是否整體回滾需要自己實(shí)現(xiàn)協(xié)調(diào)邏輯。這個(gè)問題在批量導(dǎo)入、報(bào)表生成、定時(shí)任務(wù)場(chǎng)景里非常常見。我的建議是批量任務(wù)盡量不用Transactional包整段而是每條或每批用TransactionTemplate單獨(dú)開事務(wù)配合失敗記錄表做補(bǔ)償。這樣既能保證數(shù)據(jù)一致又不會(huì)因?yàn)橐粋€(gè)線程失敗導(dǎo)致大批量回滾。1.5 數(shù)據(jù)庫引擎不支持事務(wù)這個(gè)坑現(xiàn)在少了但老項(xiàng)目中還能見到。MySQL的MyISAM引擎根本不支持事務(wù)你注解標(biāo)得再多也沒用。確認(rèn)方法很簡(jiǎn)單SHOW TABLE STATUS WHERE Name your_table;看Engine字段InnoDB支持事務(wù)MyISAM不支持。另外如果表是MyISAMSpring事務(wù)管理器初始化時(shí)也不報(bào)錯(cuò)執(zhí)行時(shí)DataSourceTransactionManager還是會(huì)調(diào)setAutoCommit(false)但引擎層面不認(rèn)等于白忙。1.6 final類或final方法CGLIB也救不了Spring事務(wù)默認(rèn)用AOP代理。如果目標(biāo)類配置了JDK動(dòng)態(tài)代理基于接口那沒問題如果走CGLIB基于類繼承生成子類那么final類無法被繼承final方法無法被重寫代理自然失效。Spring Boot 2.x之后默認(rèn)proxyTargetClasstrue走CGLIBfinal問題就浮出水面了。很多人把service類寫成final為了防繼承結(jié)果事務(wù)全失效。排查方法啟動(dòng)時(shí)看日志里是JdkDynamicAopProxy還是CglibAopProxy再看你的類和方法有沒有final修飾符。1.7 事務(wù)管理器沒配置或配置錯(cuò)了Spring Boot的DataSourceAutoConfiguration會(huì)自動(dòng)配置DataSourceTransactionManager但你如果引入了多數(shù)據(jù)源或者自定義了DataSource而沒有配套注冊(cè)PlatformTransactionManager那Transactional就會(huì)失效。另外EnableTransactionManagement注解在Spring Boot里默認(rèn)開啟不需要你重復(fù)添加。但如果你用了Spring MVC非Boot項(xiàng)目忘了加EnableTransactionManagement事務(wù)也會(huì)靜默失效。排查清單很簡(jiǎn)單Transactional方法執(zhí)行的線程棧里有沒有TransactionInterceptor有就是代理生效了沒有就是代理沒生效。2. Spring事務(wù)的底層運(yùn)作機(jī)制從JDBC到動(dòng)態(tài)代理很多人用Transactional用了好幾年但完全不知道它背后發(fā)生了什么。面試被問Spring事務(wù)是怎么實(shí)現(xiàn)的只會(huì)答AOP兩個(gè)字就再也說不出更多了。其實(shí)底層鏈路沒那么玄拆開看就三層JDBC的事務(wù)能力、Spring的事務(wù)抽象、AOP的代理包裝。2.1 第一層JDBC的事務(wù)基石萬事萬物都離不開JDBC。Spring事務(wù)再花哨落到底層就是這三行代碼Connection conn dataSource.getConnection(); conn.setAutoCommit(false); // 關(guān)閉自動(dòng)提交 conn.commit(); // 提交 conn.rollback(); // 回滾setAutoCommit(false)的意思是之后的SQL不會(huì)立即生效必須等commit()才真正寫入數(shù)據(jù)庫MySQL的binlog和redolog層面是另一套機(jī)制。如果中途異常調(diào)用rollback()之前的所有操作全部撤銷。所以Spring事務(wù)的本質(zhì)就是幫你管理Connection在合適的時(shí)機(jī)調(diào)用commit或rollback。就這么簡(jiǎn)單。2.2 第二層PlatformTransactionManager抽象Spring抽象了一個(gè)接口——PlatformTransactionManager核心方法就三個(gè)public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition); void commit(TransactionStatus status); void rollback(TransactionStatus status); }getTransaction獲取或創(chuàng)建事務(wù)。注意這里的措辭——如果你已經(jīng)在事務(wù)里根據(jù)傳播行為決定是復(fù)用當(dāng)前事務(wù)還是掛起后新建。commit提交事務(wù)。但提交前會(huì)檢查TransactionStatus里的rollbackOnly標(biāo)記如果之前有人標(biāo)記了只回滾這里會(huì)拋UnexpectedRollbackException。rollback回滾事務(wù)。常用的實(shí)現(xiàn)是DataSourceTransactionManager針對(duì)Hibernate有HibernateTransactionManager針對(duì)JPA有JpaTransactionManager。DataSourceTransactionManager的doBegin方法做了幾件事從DataSource拿一個(gè)Connection。如果當(dāng)前Connection是自動(dòng)提交模式關(guān)閉它并記下來方便事務(wù)結(jié)束恢復(fù)。設(shè)置隔離級(jí)別如果TransactionDefinition指定了。設(shè)置只讀標(biāo)志readOnlytrue會(huì)走Connection.setReadOnly對(duì)MySQL的InnoDB來說這能優(yōu)化一些查詢路徑。把這個(gè)Connection綁定到TransactionSynchronizationManager的ThreadLocal里。后面的DAO操作拿到的Connection就是從TransactionSynchronizationManager里取的。這就是同一個(gè)事務(wù)里所有SQL共用同一個(gè)數(shù)據(jù)庫連接的原理——ThreadLocal綁定。2.3 第三層AOP代理的切入點(diǎn)Spring事務(wù)的AOP基于TransactionInterceptor它實(shí)現(xiàn)了MethodInterceptor攔截所有被Transactional標(biāo)記的方法。調(diào)用鏈?zhǔn)沁@樣的外部調(diào)用orderService.createOrder()實(shí)際調(diào)用的是代理對(duì)象的方法。TransactionInterceptor.invoke()被觸發(fā)先調(diào)用TransactionAspectSupport的createTransactionIfNecessary。根據(jù)Transactional上的配置傳播行為、隔離級(jí)別、超時(shí)等調(diào)用PlatformTransactionManager.getTransaction()。執(zhí)行業(yè)務(wù)方法。方法正常返回提交事務(wù)方法拋異常根據(jù)rollbackFor配置決定是否回滾。清理ThreadLocal中的連接恢復(fù)自動(dòng)提交狀態(tài)。所以Transactional加在哪個(gè)方法上代理就攔哪個(gè)方法——事務(wù)邊界就是方法邊界。方法跑多久事務(wù)就開多久。2.4 只讀事務(wù)與UnexpectedRollbackException的真相熱詞里有一條UnexpectedRollbackException: transaction rolled back because it has been marked as rollback-only這是個(gè)非常經(jīng)典的問題。場(chǎng)景是這樣的方法A開啟事務(wù)調(diào)用方法BB標(biāo)記了rollback-onlytrue比如B捕獲了異常但內(nèi)部回滾邏輯已運(yùn)行。然后A繼續(xù)執(zhí)行正常返回時(shí)調(diào)用commit()此時(shí)Spring發(fā)現(xiàn)事務(wù)被標(biāo)記為rollback-only直接拋UnexpectedRollbackException事務(wù)回滾。換句話說你代碼里沒拋異常但事務(wù)已經(jīng)注定要回滾了。這經(jīng)常出現(xiàn)在try-catch吃了異常但沒重新拋出的情況下。排查時(shí)看日志里有沒有Transaction rolled back because it has been marked as rollback-only的WARN告警跟著調(diào)用棧就能找到是哪個(gè)方法把事務(wù)標(biāo)記了。3. 事務(wù)傳播行為與隔離級(jí)別什么時(shí)候用哪個(gè)別背口訣網(wǎng)上關(guān)于傳播行為的口訣一大堆什么REQUIRED默認(rèn)用REQUIRES_NEW記日志NESTED做嵌套背下來容易用對(duì)難。我把這幾個(gè)傳播行為逐個(gè)講透配上真實(shí)場(chǎng)景你就能理解了。3.1 傳播行為詳解Spring定義了7種傳播行為大部分項(xiàng)目用到的不超過4種但理解每一種的原理仍然重要。傳播行為含義典型場(chǎng)景REQUIRED有事務(wù)就復(fù)用沒有就新建默認(rèn)值99%的場(chǎng)景用它SUPPORTS有事務(wù)就加入沒有就無事務(wù)執(zhí)行查詢方法可選MANDATORY必須在事務(wù)中執(zhí)行否則拋異常強(qiáng)制事務(wù)的方法REQUIRES_NEW掛起當(dāng)前事務(wù)永遠(yuǎn)新建一個(gè)寫日志、異步通知NOT_SUPPORTED掛起當(dāng)前事務(wù)以無事務(wù)方式執(zhí)行導(dǎo)出大數(shù)據(jù)量文件NEVER如果有事務(wù)就拋異常強(qiáng)制無事務(wù)的執(zhí)行NESTED嵌套事務(wù)基于保存點(diǎn)Savepoint大批量循環(huán)處理單條失敗不影響整體REQUIRED是默認(rèn)值理解起來很簡(jiǎn)單Spring檢查當(dāng)前ThreadLocal里有沒有綁定事務(wù)有就加入沒有就新建一個(gè)。注意加入意味著共用一個(gè)事務(wù)、一個(gè)Connection、一套commit/rollback。內(nèi)層方法拋異?;貪L外層也一起回滾。REQUIRES_NEW的核心是掛起。邏輯是從TransactionSynchronizationManager里把當(dāng)前事務(wù)的Connection解綁、掛起然后新建一個(gè)完全獨(dú)立的事務(wù)持有獨(dú)立的Connection。內(nèi)層事務(wù)提交/回滾不影響外層事務(wù)。外層事務(wù)回滾內(nèi)層已經(jīng)提交的數(shù)據(jù)不會(huì)跟著回滾。典型場(chǎng)景就是操作日志業(yè)務(wù)方法開啟事務(wù)日志記錄要獨(dú)立提交——不管業(yè)務(wù)成功還是失敗日志都要寫進(jìn)去。如果你用REQUIRED業(yè)務(wù)回滾時(shí)日志也跟著回滾那排查問題的時(shí)候就看不到錯(cuò)誤日志了。NESTED跟REQUIRES_NEW的區(qū)別要講清楚。REQUIRES_NEW是物理事務(wù)獨(dú)立的Connection、獨(dú)立的commit/rollbackNESTED是邏輯事務(wù)基于Savepoint保存點(diǎn)。內(nèi)層方法失敗回滾到保存點(diǎn)外層可以繼續(xù)執(zhí)行外層最終提交時(shí)一起提交所有保存點(diǎn)之前的操作。但注意NESTED需要底層數(shù)據(jù)庫支持保存點(diǎn)。MySQL的InnoDB支持但有些數(shù)據(jù)庫不支持且JpaTransactionManager對(duì)NESTED的支持有限。實(shí)際項(xiàng)目中能用REQUIRES_NEW解決的就別用NESTED少踩坑。3.2 隔離級(jí)別臟讀、不可重復(fù)讀、幻讀Spring事務(wù)隔離級(jí)別有五種對(duì)應(yīng)JDBC的隔離級(jí)別隔離級(jí)別臟讀不可重復(fù)讀幻讀說明DEFAULT---使用數(shù)據(jù)庫默認(rèn)MySQL默認(rèn)REPEATABLE_READREAD_UNCOMMITTED會(huì)會(huì)會(huì)讀未提交不推薦READ_COMMITTED不會(huì)會(huì)會(huì)Oracle默認(rèn)REPEATABLE_READ不會(huì)不會(huì)會(huì)MySQL InnoDB下不會(huì)MySQL默認(rèn)SERIALIZABLE不會(huì)不會(huì)不會(huì)串行化性能最差臟讀讀到別的事務(wù)未提交的數(shù)據(jù)。不可重復(fù)讀同一事務(wù)內(nèi)兩次讀取同一數(shù)據(jù)結(jié)果不一樣因?yàn)閯e的事務(wù)提交了更新?;米x同一事務(wù)內(nèi)兩次查詢返回的記錄數(shù)不一樣因?yàn)閯e的事務(wù)插入了新記錄。MySQL的InnoDB在REPEATABLE_READ級(jí)別下通過MVCC多版本并發(fā)控制 Gap Lock間隙鎖實(shí)際上消除了幻讀問題。所以MySQL默認(rèn)的REPEATABLE_READ比Oracle的READ_COMMITTED在某些場(chǎng)景下更嚴(yán)格。實(shí)際項(xiàng)目中我見過很多團(tuán)隊(duì)把隔離級(jí)別統(tǒng)一設(shè)成READ_COMMITTED理由是MySQL的RR有間隙鎖并發(fā)插入容易死鎖。這個(gè)說法有一定道理但不是絕對(duì)的。如果你的系統(tǒng)沒有復(fù)雜的范圍查詢并發(fā)插入場(chǎng)景RR不會(huì)成為瓶頸如果你確實(shí)遇到死鎖頻繁再降級(jí)也不遲。3.3 事務(wù)超時(shí)與回滾策略Transactional(timeout 5)表示事務(wù)最多執(zhí)行5秒超時(shí)則強(qiáng)制回滾。底層實(shí)現(xiàn)是JDBC的Connection.setNetworkTimeout或者由Spring在每次SQL執(zhí)行前檢查時(shí)間不同實(shí)現(xiàn)有差異。但要注意timeout是從事務(wù)開始到最后一次SQL執(zhí)行的時(shí)間不是方法總耗時(shí)。如果你的方法在事務(wù)前做了一堆耗時(shí)操作比如遠(yuǎn)程調(diào)用這部分不計(jì)入事務(wù)超時(shí)。所以不要指望timeout能保護(hù)整體方法執(zhí)行時(shí)間。關(guān)于回滾策略我再強(qiáng)調(diào)一次// 推薦寫法 Transactional(rollbackFor Exception.class) // 或者只回滾特定異常 Transactional(rollbackFor BizException.class, noRollbackFor IllegalStateException.class)noRollbackFor用的場(chǎng)景不多但有一種情況很實(shí)用某些非關(guān)鍵數(shù)據(jù)比如統(tǒng)計(jì)緩存的更新失敗不應(yīng)該讓主事務(wù)回滾可以列在noRollbackFor里。4. 編程式事務(wù)當(dāng)Transactional真的不合適時(shí)Transactional是聲明式事務(wù)用起來方便但有三個(gè)致命弱點(diǎn)事務(wù)粒度太大整個(gè)方法一個(gè)事務(wù)如果方法里有網(wǎng)絡(luò)調(diào)用或批量循環(huán)事務(wù)會(huì)長時(shí)間占用數(shù)據(jù)庫連接。自調(diào)用失效前面已經(jīng)講過了。無法精確控制提交時(shí)機(jī)想先做幾步提交再繼續(xù)做Transactional實(shí)現(xiàn)不了。這時(shí)候就該上手編程式事務(wù)了。Spring提供了TransactionTemplate。4.1 TransactionTemplate的用法Service public class OrderService { private final TransactionTemplate transactionTemplate; public OrderService(PlatformTransactionManager transactionManager) { this.transactionTemplate new TransactionTemplate(transactionManager); // 可以設(shè)置默認(rèn)配置 this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); } public void createOrder(OrderDTO dto) { transactionTemplate.executeWithoutResult(status - { stockMapper.deduct(dto.getSkuId(), dto.getQuantity()); orderMapper.insert(buildOrder(dto)); }); } }TransactionTemplate.execute回調(diào)里你可以在任何地方開啟事務(wù)塊粒度完全由自己控制。更重要的是它徹底繞開了自調(diào)用問題——因?yàn)槟闶侵苯诱{(diào)用事務(wù)管理器不走代理。還有一個(gè)場(chǎng)景強(qiáng)烈推薦用TransactionTemplate大批量循環(huán)插入。如果用Transactional包住整個(gè)for循環(huán)幾萬條數(shù)據(jù)一個(gè)事務(wù)提交時(shí)數(shù)據(jù)庫壓力巨大一旦失敗全部回滾代價(jià)太高。改成循環(huán)內(nèi)用TransactionTemplate每100條一個(gè)事務(wù)失敗了只回滾這一批配合日志記錄失敗批次整體效率和可靠性都高很多。4.2 手動(dòng)控制TransactionStatus如果execute回調(diào)不適合你比如需要事務(wù)中間做分支判斷、需要中途提交可以用更底層的PlatformTransactionManagerAutowired private PlatformTransactionManager transactionManager; public void complexBiz() { DefaultTransactionDefinition def new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status transactionManager.getTransaction(def); try { // 業(yè)務(wù)邏輯1 dao.update(...); // 到這里先提交一次 transactionManager.commit(status); // 開啟新事務(wù) TransactionStatus status2 transactionManager.getTransaction(def); try { // 業(yè)務(wù)邏輯2 dao.insert(...); transactionManager.commit(status2); } catch (Exception e) { transactionManager.rollback(status2); throw e; } } catch (Exception e) { transactionManager.rollback(status); throw e; } }這段代碼展示了如何手動(dòng)控制多段事務(wù)但我強(qiáng)烈不建議在業(yè)務(wù)代碼里寫這種底層代碼——容易出錯(cuò)而且代碼很難讀。99%的場(chǎng)景TransactionTemplate夠用了。4.3 編程式事務(wù)的注意點(diǎn)TransactionTemplate是線程安全的可以做成Bean注入不要每次new一個(gè)。executeWithoutResult和execute的區(qū)別后者可以返回業(yè)務(wù)結(jié)果前者只能執(zhí)行不能返回。需要返回值就用execute。事務(wù)回調(diào)里拋出的異常RuntimeException會(huì)觸發(fā)回滾檢查型異常默認(rèn)不會(huì)。要回滾檢查型異常需要手動(dòng)status.setRollbackOnly()或者包裝成RuntimeException。5. 多數(shù)據(jù)源與分布式事務(wù)跳出單庫思維的邊界單庫單事務(wù)的好日子總有到頭的時(shí)候。微服務(wù)一拆、分庫一搞Transactional就管不住跨庫的數(shù)據(jù)一致性了。我先講清楚Spring事務(wù)在多數(shù)據(jù)源下的表現(xiàn)再展開分布式事務(wù)。5.1 多數(shù)據(jù)源下的事務(wù)各管各的如果你配置了兩個(gè)DataSource比如一個(gè)主庫一個(gè)從庫Spring里注冊(cè)了對(duì)應(yīng)的兩個(gè)PlatformTransactionManager同一個(gè)Transactional方法里操作了兩個(gè)庫——那這兩個(gè)庫的事務(wù)是互相獨(dú)立的。主庫提交成功、從庫提交失敗你沒有任何辦法通過單機(jī)事務(wù)解決。Spring Boot里處理多數(shù)據(jù)源的常規(guī)姿勢(shì)是Transactional(transactionManager xxxTransactionManager)指定用哪個(gè)事務(wù)管理器。方法里操作另一個(gè)庫那份數(shù)據(jù)不在事務(wù)保護(hù)范圍內(nèi)。所以多數(shù)據(jù)源場(chǎng)景下的策略是一個(gè)事務(wù)只操作一種數(shù)據(jù)源??鐢?shù)據(jù)源的業(yè)務(wù)要么拆分方法要么引入分布式事務(wù)方案不要指望Transactional救你。5.2 分布式事務(wù)的主流方案對(duì)比分布式事務(wù)是個(gè)大話題我只挑主流方案講給個(gè)選型思路。XA協(xié)議兩階段提交2PCXA是最正統(tǒng)的分布式事務(wù)協(xié)議分兩步準(zhǔn)備階段所有參與者執(zhí)行SQL但不提交各自保留Undo/Redo log和提交階段協(xié)調(diào)者發(fā)提交指令各參與者提交。問題在于準(zhǔn)備階段會(huì)一直持有數(shù)據(jù)庫鎖高并發(fā)場(chǎng)景下鎖沖突嚴(yán)重性能非常差。Java里典型的實(shí)現(xiàn)是Atomikos、Bitronix。說實(shí)話互聯(lián)網(wǎng)高并發(fā)場(chǎng)景用XA的很少了更多出現(xiàn)在金融等強(qiáng)一致性要求的內(nèi)部系統(tǒng)。TCCTry-Confirm-CancelTCC把每個(gè)操作拆成三個(gè)階段Try預(yù)留資源、Confirm確認(rèn)執(zhí)行、Cancel取消釋放。優(yōu)點(diǎn)是業(yè)務(wù)層面控制粒度性能比XA好很多缺點(diǎn)是侵入性極強(qiáng)每個(gè)業(yè)務(wù)都要寫三套邏輯。典型場(chǎng)景賬戶轉(zhuǎn)賬。Try階段凍結(jié)轉(zhuǎn)出金額Confirm階段扣款Cancel階段解凍。這個(gè)方案需要深入理解業(yè)務(wù)才能寫得對(duì)如果你只是想快速實(shí)現(xiàn)一個(gè)分布式事務(wù)TCC的學(xué)習(xí)成本挺高的。消息事務(wù) 最終一致性這是目前最常用、成本最低的方案。思路很簡(jiǎn)單利用本地事務(wù)把業(yè)務(wù)操作和發(fā)消息綁定在同一次數(shù)據(jù)庫事務(wù)里通過消息中間件RocketMQ/RabbitMQ最終把數(shù)據(jù)變更同步給其他服務(wù)。舉個(gè)訂單和積分的例子開啟本地事務(wù)插入訂單表同時(shí)插入積分消息表。本地事務(wù)提交后后臺(tái)任務(wù)或MQ的事務(wù)消息機(jī)制把積分消息表里未發(fā)送的記錄發(fā)到MQ。積分服務(wù)從MQ消費(fèi)消息給用戶加積分。如果積分服務(wù)失敗消息進(jìn)入重試隊(duì)列直到成功。這種方案做不到強(qiáng)一致中間會(huì)有一段數(shù)據(jù)不一致的時(shí)間窗口但絕大多數(shù)業(yè)務(wù)都能接受。核心機(jī)制是本地消息表實(shí)現(xiàn)成本低、不用引入重量級(jí)中間件是目前國內(nèi)互聯(lián)網(wǎng)公司的首選方案。Seata的AT模式Seata是阿里開源的分布式事務(wù)框架AT模式的思路是代理你的SQL記錄Before Image和After Image數(shù)據(jù)快照在全局提交時(shí)自動(dòng)執(zhí)行補(bǔ)償SQL。對(duì)業(yè)務(wù)代碼侵入性很小但性能有一定損耗每行數(shù)據(jù)要記錄前后快照。如果你的系統(tǒng)需要跨服務(wù)事務(wù)、又不想太動(dòng)代碼Seata AT是可以考慮的。5.3 選擇建議場(chǎng)景推薦方案單體應(yīng)用單數(shù)據(jù)庫什么都不用本地事務(wù)夠用微服務(wù)對(duì)一致性要求不高本地消息表 MQ最終一致微服務(wù)強(qiáng)一致要求高Seata AT 或 TCC金融級(jí)強(qiáng)一致低并發(fā)XA/2PC非核心數(shù)據(jù)可以容忍短暫不一致MQ異步 對(duì)賬補(bǔ)償分布式事務(wù)沒有銀彈。選型的核心不是哪個(gè)方案高級(jí)而是你的業(yè)務(wù)能容忍多大程度的不一致。6. 事務(wù)排查工具箱從日志到監(jiān)控的一整套姿勢(shì)事務(wù)的問題一旦出現(xiàn)往往都是線上的、隱性的、難復(fù)現(xiàn)的。所以一定要有一套預(yù)防和排查的手段而不是等出了問題再手忙腳亂。6.1 日志配置把事務(wù)邊界打印出來Spring的事務(wù)日志默認(rèn)是DEBUG級(jí)別不打開根本看不到。在application.yml里配置logging: level: org.springframework.transaction: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager: DEBUG org.springframework.jdbc.datasource.JdbcTransactionManager: DEBUG打開后你會(huì)看到類似這樣的日志Obtained JDBC transaction from DataSource [HikariDataSource (HikariPool-1)] Participating in existing transaction Initiating transaction commit Initiating transaction rollback這些日志的排列能幫你快速判斷事務(wù)有沒有開啟、是新建還是復(fù)用、提交還是回滾、有沒有因?yàn)閞ollback-only被強(qiáng)制回滾。6.2 ThreadLocal狀態(tài)的運(yùn)行時(shí)監(jiān)控如果你懷疑某個(gè)方法執(zhí)行時(shí)事務(wù)狀態(tài)不對(duì)可以在代碼里手動(dòng)檢測(cè)import org.springframework.transaction.support.TransactionSynchronizationManager; boolean isInTransaction TransactionSynchronizationManager.isActualTransactionActive(); System.out.println(當(dāng)前是否在事務(wù)中: isInTransaction);isActualTransactionActive()返回true說明當(dāng)前線程確實(shí)有數(shù)據(jù)庫事務(wù)處于活動(dòng)狀態(tài)。如果外面標(biāo)了Transactional但這里返回false說明代理沒生效——自調(diào)用、final方法、私有方法逐個(gè)排查。還可以查看當(dāng)前事務(wù)名Object name TransactionSynchronizationManager.getCurrentTransactionName();這能幫你快速定位當(dāng)前事務(wù)是哪個(gè)方法開啟的。6.3 監(jiān)控事務(wù)耗時(shí)與連接占用事務(wù)另一個(gè)容易忽略的問題是連接泄漏和長事務(wù)。一個(gè)事務(wù)如果執(zhí)行了幾十秒連接就占用了幾十秒連接池很快被打滿。建議做法在DataSource層加慢SQL日志HikariCP有connectionTimeout、validationTimeout配置同時(shí)開啟leakDetectionThreshold檢測(cè)連接泄漏。用TransactionSynchronizationManager.registerSynchronization注冊(cè)事務(wù)同步回調(diào)統(tǒng)計(jì)每個(gè)事務(wù)的耗時(shí)。Transactional public void bizMethod() { long start System.currentTimeMillis(); TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { Override public void afterCompletion(int status) { long cost System.currentTimeMillis() - start; if (cost 1000) { log.warn(事務(wù)耗時(shí)過長: {}ms, status{}, cost, status); } } }); }這個(gè)方法能精確定位哪個(gè)事務(wù)方法最耗時(shí)但它需要每一個(gè)業(yè)務(wù)方法都加一遍侵入性強(qiáng)。更好的方案是寫一個(gè)AOP切面統(tǒng)一攔截Transactional方法做耗時(shí)統(tǒng)計(jì)。6.4 事務(wù)失效排查的標(biāo)準(zhǔn)操作流程如果線上出現(xiàn)了疑似事務(wù)失效的問題我的排查順序是這樣的看日志打開事務(wù)DEBUG日志確認(rèn)方法執(zhí)行時(shí)有沒有Obtained JDBC Transaction記錄。沒有就是代理沒生效走第2步有就繼續(xù)看提交/回滾記錄走第5步??捶椒ê灻遣皇莗ublic類或方法有沒有final看調(diào)用方是不是同一個(gè)類內(nèi)部調(diào)用是不是沒有被Spring管理的對(duì)象比如new出來的看注解Transactional有沒有寫對(duì)rollbackFor有沒有配多數(shù)據(jù)源下transactionManager指對(duì)了沒有看異常異常有沒有被try-catch吞掉異常類型是不是RuntimeException看數(shù)據(jù)庫表引擎支不支持事務(wù)連接是不是走到了正確的DataSource這套流程走一遍90%的事務(wù)問題都能定位。7. 最后的實(shí)戰(zhàn)建議事務(wù)規(guī)范從我做起寫到這里我把這些年跟事務(wù)打交道沉淀下來的幾條規(guī)矩放在最后算是個(gè)人的實(shí)戰(zhàn)總結(jié)也是新項(xiàng)目啟動(dòng)時(shí)的檢查清單。事務(wù)方法要短小精悍。事務(wù)范圍之內(nèi)不要做遠(yuǎn)程調(diào)用、不要做復(fù)雜的文件IO、不要進(jìn)行大批量循環(huán)。否則連接池遲早被打死。把非數(shù)據(jù)庫操作移到事務(wù)外或者拆成多個(gè)事務(wù)塊。事務(wù)邊界要盡可能晚開啟盡可能早提交。前置校驗(yàn)、參數(shù)組裝這些放事務(wù)外真正需要數(shù)據(jù)庫原子性的操作才放進(jìn)事務(wù)塊。很多人習(xí)慣方法一進(jìn)來就開事務(wù)其實(shí)很多操作根本不需要事務(wù)保護(hù)?;貪L配置要顯式寫。Transactional(rollbackFor Exception.class)這行字雖然啰嗦但它能擋住95%的回滾失效問題。自定義的業(yè)務(wù)異常統(tǒng)一繼承RuntimeException省得每個(gè)方法都要考慮這個(gè)異常會(huì)不會(huì)回滾。批量處理用TransactionTemplate而不是Transactional。循環(huán)里的事務(wù)一定要用編程式事務(wù)精確控制粒度Transactional包整個(gè)循環(huán)就是把數(shù)據(jù)庫往死里逼。分布式事務(wù)不要貪多求全。能靠業(yè)務(wù)流程設(shè)計(jì)規(guī)避的就盡量規(guī)避比如通過本地消息表做最終一致性比引入一套重量級(jí)分布式事務(wù)框架劃算得多。選型之前先想清楚你的數(shù)據(jù)不一致容忍度。事務(wù)這個(gè)東西說到底是數(shù)據(jù)庫連接和錯(cuò)誤處理時(shí)機(jī)的管理藝術(shù)。理解底層機(jī)制比背多少面試題都管用。希望這篇文章里踩過的坑、總結(jié)的思路能讓你少走幾條彎路。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
精品大全99999| 狠狠干综合| 日噜夜夜夜夜夜夜夜夜夜夜爽爽爽爽爽爽爽爽爽爽爽爽 | 亚洲国产成人精品999| 亚洲网污污污污| 91人人臊| 国产偷拍自拍在线视频| 国产精品爆乳懂色蜜乳| 男人的天堂kva| 色婷婷综合久久中文字幕雪峰| 操逼片中文| 久久这里只精品免费福利| 另类图片五月天| 久九色| 亚洲性猛交| 婷婷色色五月天| 久久久久久日韩| 伊人影院日本| 91久久青青草原精品| 亚欧美综合网。| 亚洲第一页欧美| 日韩AV片| 天堂av2019| 久久久成人国产精品无码| 亚洲免费成人在线高清无码视频| 欧美性爽xyxOOOO| 欧美一级二级三级| 99久久久无码国产精品性啊聊| 91麻豆天美国产欧美高潮| 国产乱弄免费在线视频。| 性感女人网页在线观看视频| 色一情一乱一乱一区91Av| 亚洲一级性爱视频免费看| av毛片aaaaa免费看| 欧美色图20p| 亚洲天堂2020| 日本成a人v网站在线观看| 欧美狠狠狠| 日本三级韩国三级美三级91| 天天干1区2区在线| 中文字幕精品专区搜索结果91| 97国伦国色| 在线综合 亚洲 欧美中文字幕 | 99999精品视频| 青青操97| 欧美熟妇亚洲版| 91国产美女丝袜足交精品视频 | 国产一区二区三区高清视频| 青娱乐福利99| 久久久久久亚洲Av无码| 高清成年美女黄网站免费大全 | 大香蕉亚洲中文| 日本三级中国三级99人妇网站| 中文字幕亚洲在线一区| 欧美制服网站美腿丝袜| 欧天美中出| 久久久久久久9最新免费视频观看| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 色偷偷2020免费视频播放| 夜夜做夜夜爽精品视频| 综合五月天| 亚洲高清视频在线免费观看| 无码黑人精品一区二区三区三| 3p国产欧美99热| 男女激情中文字幕| 啊啊啊在线观看免费视频| 自拍丝袜美腿人妻| 青青伊人加勒比海| 97碰久久| 永久免费av无码网站国产app| 中文字幕一区二区三区高清| 超碰狠狠操| av优播| 久久久久久九九九九-美女久久久久久久-成人AV | av网站在线观看了| 亚洲男人的天堂亚洲| 久久99黄色卞西瓜| 97精选久久| 亚洲九九视频| 久久精品色欧美aⅴ一区二区| 九色97| 97视频900| 91性片| 老熟女乱伦一区| 五月婷在线| 伊人国产视频| 欧美综合自拍| 亚州情色j区| 九九超碰综合网| 久久久人妻| 久久伊人最新网址视频| 视频一区二区免费在线| 丝袜熟女一区二区三区| 色性荡荡荡荡视频| 精品国产乱码久久久久久日本公司| 尤物视频偷拍免费| aV中文麻| 欧美丝袜制服久久| 性交一区二区在线播放| 欲香欲色| 久悠悠av| 97精品在线| 中文字幕丰满子伦无码专区在线视频最新 | 国产亚洲精品第一最新| 少妇被玩视频二三区| 精品日韩产品在线,日韩在线不卡视频,欧美日韩免费专区/久, | 91麻豆天美国产| 色逼综合| 亚洲不卡不卡中文字幕不卡 | 天天在线91| 中文字幕一区二区日韩网| 亚洲另类久操网| 国产日韩中文字幕欧美| 国产剧情AV不卡在线观看| 野狼激情网| 久久婷婷电影网| 伊人久久艹| 国产成人精品一区| 中文字幕乱在线伦视频中文字幕乱码在线 | 九月AV| 精品综合久久久久久五月天| 麻豆 欧美 日韩| 好吊色综合| 亚洲男人天堂2019| 天天谢天天干| 国产午夜福利合集| 日韩人妻精品久久久久| 天堂69亚洲精品中文字| 亚州熟妇精品| 青青操97| 黄片在线免费在线观看| 99re6国产精品99re| 人人操人人肉久久精品| 人妻 中文 日韩| 蜜桃av色偷偷av老熟女| 99久久婷婷国产综合精品草原| 久久人妻精品| 国产黄片精品在线| 色一射色一射| 免费的黄片有限公司| 精品无码产区一区二| 亚洲国产第一页综合视频| 秋霞操逼片| 亚州欧美综合| 亚洲精品 欧美精品| 992这里有精品| 欧美三级不卡| 啊视频在线| 久久黄色视频一区二区三区| 黑人性暴力毛片| 久久久免费视频18| 欧美日日夜夜| 国内精品999| 97人人操人人摸| 91老女人| 久久少妇| 日韩AV无码网站| 偷拍新久久| 日本天天干天天搞一区| 亚洲人在线成线成人| 日本人妻A片成人免费看片| 日本成熟少妇A∨网站| 婷婷五月天色网| 亚洲一区二区专区-国产丝袜精品丝袜-成人AV | a啊啊啊啊啊啊啊啊一区二区| 天堂亚洲精品| 青娱乐休闲视频在线观看| 熟妇人妻丰满久久久久久久无码 | 亚洲在线| 美欧色综合| 久久婷婷成人综合色怡春院| 蜜臀va69| 校园激情狠狠四射| 亚洲精品久久久久毛片A片拉屎 | 人妻在线视频| 人人操肉肉| 十八禁视频一区二区| 97亚洲综合| 国产精品直播在线观看直播| 国产精品探花视频| 一本正道久久熟女| 日韩欧美麻豆| 日本亚洲vr欧美不卡高清专区| 亚洲无套久久嗯嗯| 欧美综合传媒| 中文字幕美女91| 免费一级视频特黄色大片| 强奸乱伦av电影| 人人人人人人少妇| 在线观看啊啊啊啊啊| 亚洲加勒比| 能直接看AV的网站| 少妇熟女视频一区二区三区| 欧美性爱18观看| 亚洲乱码国产乱码精网站| 日本精品性生活久久久| 午夜精品久久99蜜桃的功能章节| 久久 国产精品 一区| 欧美玖玖爱免费玖玖| 极品另类| 欧美色97| 婷婷精品视频| 97超碰超| 有码人妻系列| 国产精品不卡一区二区三区av| 啊啊啊好爽快点啊啊啊嗯嗯| 国产精彩女在线观看视频| 中国小夫妻勾搭露脸淫荡对白| 91五月天| 中国国产精品一区视频| 国产三区免费在线观看| 天天影视综合网欧美精品| 欧美一级做a爰片免费视频| 99天天超碰| 色爱天堂| 国产久久视频| 人看人人摸人人操| 蜜臀久久99精品久久久久久成人小说 | 97碰碰日本乱偷人妻中文的| 三级AV入口| 嗯嗯啊啊好疼| 日本久久天堂| 91c色| 久艹视频在线| 欧洲亚洲人妻无码高清久久三区四区| 78m成人视线| 日韩在线欧美精品一区二区| 极品内射| 天天综合~91入口| 91性高朝久久久久久久久| 久久人妻办公室视频| 99re视频在线播放青草| 日日橹狠狠爱欧美超碰| 美女写真| 超碰在线观看av不卡| 天美传媒麻豆一区二区三区国产精| 色噜噜国产在线| 久久婷婷色| 黄页网站免费高清在线观看| 男女啪啪网站免费视频| 国产免费内射视频| 躁躁躁日日躁2020| 美女性91| 91精品在线播放| 欧美激情色婷婷花野真衣一区二区| 99热精品在线| 丁香五月影院| 五月天伊人| 国产乱色国产精品免费视| 97超碰碰| 欧美黑人熟妇精品91| 超碰 国产熟女精品一区| 欧美激情五月天| 久久精视频美日韩在线视频| 丁香五月影院| 国产精品一区二区在钱播放| 麻豆天美久久91| 静品嫩模一区二区| 亚码激情| 91+欧美| 操我啊啊啊啊啊| 91亚·色| 69精品| 老熟妇91| 变态乱伦伪娘灌肠一区二区| 插日本熟女视频| 久久精品日韩| 99精品久久久久久久婷婷蜜桃| 五月色综合| 狠狠狠狠狠| 毛片视频白嫩| 国产九九九九九九| 亚洲se91| 很黄很色的视频在线观看| 人人看欧美性爱| 日韩精品1区2区中文字幕| 中国女人内射6XXXXX| 日操粉逼逼| 校园春色制服丝袜中文字亚洲| 九九九久千久久激情蜜桃在线看 | 殴美性色a级欧美| 精品无码久久久久| 好屌色综合| 日日橹狠狠爱欧美超碰| 精品国产肉丝袜在线拍国语| 色噜噜人妻丝袜a∨先锋影 | 国产精品毛片| 亚洲天堂在线怕怕视频| 秋霞影音一区二区三区| 久久免费精彩视频| 91路www| 一区二区视频在看| 国产精品白领在线观看| 久久性爱城| 欧美成人一区二区| 亚洲欧洲成人在线电影| 在线视频日韩欧美国产| 大香蕉色网| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区 | 国产女同在线观看视频| 午夜精品视频777| 麻豆精品A片免费观看| 亚州色图片在线色| 五月激情天| 性色avv| 97欧美综合网| 91粉芽高清在线一区二区| 成人资源中文字幕在线观看| 2020中文在线一区二区三区| 久久国产视频性吧 | 亚洲1区2区三区高清中文字幕| 色99色| 久9爱精品| 亚洲欧美国产其他二区| 日韩人妻一二三区视频| 九九九久久久久| 果冻传媒A片麻豆熟妇人妻| 国产黄色 A 片免费看| 超碰97色色| se吧提供91精品国产91久久久久久| renqi久久久久久久久久久久| 欧美劲爆视频一区二区| 亚洲精品久久一区二区三区蜜桃臀| 秋霞一级A片黄色视频| 国产美女激情| 最新日韩黄片| 欧美狠狠干| 防屏蔽在线视频| 成年在线视频日本亚洲在线视频区精品江靖宇公司 | 人妻 中文 日韩| 欧美丝袜激情| 国产精品探花在线| 亚洲色性| 久操视频免费在线观看| 久久超碰网| 日人妻视频91| 亚洲国产日韩精品久久久| 天美麻花大全视频| 久久春色| 久操在97| 国产精品熟女乱伦| 日韩一级二级三级免费看完整版| 久久久久久亚洲精品中文字幕人妻| www国产无码| AV乱伦国产| 狠插 制服 自拍| 人人摸人人叼| 亚洲综合欧美| 久久熟女精品不卡一区| 久都青青视频| 久久精品久久九九精品| 久久久久久久精| 久久熟女久| 综合久草| 极品五月天噜噜| 图片区小说区| 97在线精品观看视频| 碰碰97| 天天综合站| 亚洲情色五月天| 日韩,欧美,中文在线| 玖草在线视频| 欧美男人的天堂| 色综合久久夜色精品国产天堂| 日韩日韩日韩-国产乱码精品一区二区| 九九色色| 久久婷婷六月综合| 午夜福利免费精品视频| 97免费在线视频| 欧美操逼录像国产黄色国产| 中文字幕精品三级久久久| 亚洲情色一区综合| 97国产超湿| 国产视频不卡在线观看| 欧美aaaaaaa| 在线无码操| AV综合中文字幕干| 久久久工口| 四虎永久在线精品免费网址| 中文一区二区婷婷视频| 欧美色图天堂网m| 男人的天堂激情| 婷婷久久综合| 夜夜操二区| www.四虎在线| 欧美超碰96| 中文乱码99| 欧美色图自拍| 欧美人妻少妇| AA级电影三区| 亚洲av综合色| 五月丁香啪啪啪| 老熟女熟妇| 韩日巨乳美女免费视频在线观看| 超碰地址97| 天久久久噜噜噜久久国产精品爽爽| 国内亚洲高清无码| 免费啪啪啪网站18岁| 九久9热| 青青草玖玖爱| 欧美成年人性爱视频免费观看| 亚欧日韩成人| 国产美女91视频| 男人天堂东京热| 操逼www.| 男人把坤坤插入女人的下体| 国产精品久久| 黑操B| 高清国产精品无码| 亚洲午夜AV| 999综合色| 亚洲欧美日韩免费观看| 91性高潮久久久久久久久| 日韩无码AB| 国产免费黄色一级大片| 人妻久久久久久| 国产乱码久久久| 乱伦AVxx| 婷婷九月丁香| 亚洲成人美女无吗| 亚洲熟女乱综合一区二区在线-...亚洲国产日韩欧美一区二区三区,久久久久久精 | 91综合无码| 久热无码| 97超碰超碰| 床上啊啊啊一区二区三区| 熟妇一区,二区,三区。| 日韩一级特黄av毛片| 人人爽人人精品乱人伦AV| 亚洲日韩精品久久久久一区壹牛 | 午夜一区| 91狠狠综合久久久久久| av网站国产主播在线| 国产精品视频电影| 天天干人人干天天日97| 一区e区三| 99久久久久久久久| 91东北熟女| 蜜桃一区二区三区| 色爱国产| 高潮内射在线| 免费观看性欧美一级| 亚洲国产蜜臀系列在线观看| 亚洲啪啪性视频| 免费人成毛片乱码| 婷婷探花久久精品一区| 亚洲av乱伦色图网站| 全国男人天堂网| 97超碰免费人人性爱| 国产乱伦性爱AV| 免费男人的天堂| 日韩av三四区| 婷婷丁香六月天| 色黄色美女大长腿午夜视频| 免费视频一二三区| 97天天插| 歐美性天天| 久久精品国产精品亚洲艾通辽熟妇 | 色欲日韩欧美在线一区| 九九九九九九亚洲| 国产精品香蕉热久久新品| 伊人骚琪琪亚洲天堂网站| 亚州欧美综合| 国产蜜臀精品一区免费尤物| 全球成人中文在线| 亚洲欧美国产其他二区| 影音先锋少妇| 日韩黄片视频试看| 国产成人无码a| 蜜臀久久久99久久久久 | 91福利网在线观看| 好爽视频在线观看视频 | 97网址97| 日韩无码服务区| AV色五月天| 一本久久精品中文字| 日日狠狠久久偷偷色综合免费| 久久无码电影| 亚洲精品三| 一区在线观看中文字幕| 亚洲欧美日韩中文久久自慰| 99色在线| 成人免费性爱视视| 翔田千里一区二区三区奶水| 成人日本视频人妻在线| 久久午夜伦| 天美国产三级传媒| 97 视频在线| 亚洲综合另类色图| 91亚州| 欧美αv.com| 秋霞一级视频在线观看免费| 久久精品人体| 91精品操美女| 99精品视频在线观看免费| 好吊妞转入那个网| 骚女高跟AV在线| 97国产综合欧美| 97国产精品在线观看| 熟妇乱伦一区二区| 333kkkk·亚洲com久久| 澳门成人网站久国产日韩| 亚州春色| 91超碰在线| 日韩一级特黄av毛片| 天天爽天天操| 男人的天堂日韩| 久操视频在线观看| 欧美丰满熟妇XXXX性ppX人交| 五月丁香| 亚洲国产综合图区中文字幕 | 亚洲一二三四区| 翔田千里A片一区二区| 女人高潮大叫一级毛片| 亚洲色悠悠久久88| 亚洲国产精品无码AV久久久| 99热这里只有精| 综合熟妇一区二区三区| 日本操嫩b网| 天天影视射综合网| 蜜乳AV免费观看| 嗯嗯嗯啊啊啊在线免费观看| 亚洲欧美电影| 国产熟妇一区二区| 天天激情综合站| 亚洲欧美日韩电影网站一区 | 岛国小电影| 久久久久久九九九| 久久大香蕉手机高清| 5252色欧美在线男人的天堂| 亚洲1区| 亚洲中文sv| 超碰人人妻| 免费在线看黄片av| 一区二区 电影 亚洲| 三级精品三级在线观看| 狠狠干妹子| 综合久| 丝袜 中出 制服 人妻 美腿 中文字幕| 天天看,天天做| 国内外激情在线| 男人的天堂.com| 再深点灬舒服灬太大了添视频 | 97视频免费在线| 久久小视频| 欧美一区二区三区互相| 色香天天| 亚州综合在线| 997色在线| 中文字幕一二三区| 色噜噜综合网| 久久首页| 九九九九九九视频| 1024日韩| 久久国语| 久久久久亚洲熟妇熟女| 综合av社区| 另类小说五月天| 奸色色 男人天堂 天天射| 国产福利视频精品视频| 91 天天综合| 九X超碰| 99色视频| 91色久| 久久久久成人亚洲国产| 日韩免费三级黄片电影| 欧美在线91| 欧美超碰在线| 青娱乐休闲视频在线观看| 久久机热| 欧美日韩精品久久久久东北老熟妇| 九X超碰| 久久婷婷国产一区二区色| 亚洲最大无码中文字幕网站| 九九久久一区二区伦理| 黑人无码一区二区| 国产精点久久久成人| 免费的黄片wwwwww| 日韩午夜啪啪视频| 操操啪| 精品妇女一区二区三区| 伊人久久青青草| 久久国产99精品72福利| 91艹逼精品| 人妻少妇三级| 超碰在线97国产| 丝袜综合| 欧美激情黑人| 在线中文字幕视频| 八戒午夜福利理论片| 色狠狠 - 百度| 日韩性爱再线视频| 九九色精品| 人妻一区二区三区| 福利在线视频一区二区| 国语精品对白| 国产精品福利资源在线尤物| 日韩乱伦AⅤ| www狠狠| 99精品久久久久久| av毛片aaaaa免费看| 大学生口爆吞精| 亚洲综合精品国产一区| 色色99| 亚洲阿v天堂在线| av网站免费看| 亚洲天堂第一页| 无码一区免费在线不卡| 91超碰人人| 久久免费少妇| 久偷拍| 国产家庭乱伦性爱视频| 亚洲狼狼干综合1| 亚洲天堂中文字| 91路www| 日韩精品黄片免费观看| 天天影视综合色| 操美女高潮抽搐白浆| 任你干在线视频| 加勒比在线视频一区二区三区| 日韩78m视频| 久久99午夜精品一区人妻| 日日日日做夜夜夜夜做无码97| 强奸乱伦大香蕉网| 欧美日韩狠狠爱| 天天香香欲综合| 操逼操网| 天天日天天干天天操| 亚洲永久AV无码精品秋霞| 亚洲成人性爱网站在线播放| 九九九九九九九九九九九蜜桃| 国产黄色av大片网站| 欧美综合中文| 97亚洲资源| 熟女突然公开看18禁影片| 水滴偷拍| 色综合久久夜色精品国产天堂| 国产美女mm131爽爽爽爽| 亚洲黑人在线| 色噜噜狠狠色综无码久久| 人妻少妇久久久| 国产亚洲精品美女久久久久久2021| 另类老少妇| 青青草在线视频欧美| 免费看一级a性色生活片久久无| 91网站18禁| 黑人粗大V S日韩女优视频| 狠狠欧美| 少妇一线天久久久久久| 免费视频a级毛片免费视频| 欧美高清18A片| 精品高潮| 26uuu性| 黄色免费一级在线毛片| 在线国产福利网址导航| 久久久久骚| 夜夜操美女| 精品视频一区二区| 日韩天堂av电影在线观看| 亚乱色| 乱抡国产91| 欧美加勒比| 97在线资源| 偷拍欧美激情| 日本精品一区二区中文字幕| 欧美日韩亚洲国产中文永久天天看| 色婷婷电影| 大屁股人妻女教师撅着屁股| 亚洲色图欧美色图另类图片| 激情综合网一盗摄| 另类 综合 日韩 欧美 亚洲| 日本高清有码网址视频| 在线欧美69V免费观看视频| 亲子敌伦对白在线播放| 91美女视频直播| 亚州 综合 色图| 成人情色一区二区| 日本中文字幕在线电影| 免费簧片在线观看| 日韩AC| 天美传媒国产原创中文字幕亚洲欧美另类| 久久亚洲婷婷| 97干在线看| 97爱爱爱综合| 亚洲色图加勒比| 99热18| 91久久久久免| 高清无码网址| 欧美一区二区情色| 激情视频一二三| 啊啊啊啊嗯嗯在线久久久| 偷拍综合网| 成年人三级黄色片视频| 欧美Ⅴ性爱| 国产无码三级视频在线观看| 国产精品黑人一区二区三区| 超碰av在线| 国产欧美伊人| 997色在线| 日日夜夜精品视频| 欧美日韩中文亚洲v在线综合| 蜜臀国产AV中文字幕| 久久AV色| 秋霞色色影院| 午夜寂寞欧美| 欧美亚综合色图| 欧美体内射精| 欧美色图综合| 久久久婷婷| 蜜臀AV一区二区三区激情综合| 蜜臀一二三| 亚洲性爱成人| 超91综合网| 大粗鳼巴久久久久| 日韩视频啪啪| 天天综合站| 日本精品无码三级网站| 蜜臀亚洲中文| 中文字幕永久在线| 黄色交缠性感爆操91国产精品免费一区二区三区 | 蜜臀AV成人精品蜜臀| 激情综合网激情综合| 丁香激情网| 蜜桃久久一区| 大香交伊人网| 国产精品久久久久9999小说| 女人被添高潮免费视频| 青木玲在线不卡| 欧美性爱91| 国产老熟女| 97视频在线播放| 看黑丝美女操逼青青网站| 97超碰欧美| 99re这里只有精品3| 老司机福利青青草| 午夜毛片高清免费不卡| 久久91精品国产9丨久久分亭 | 一区二区三区无卡视频在线观看| 人妻少妇久久中文字幕一区二区 麻豆| 欧洲熟妇xxXx欧美老妇裸体| 超碰97.com| 久久精品欧美一区蜜桃| 人人爱人人乐人人操| 欧美性爱一区二区三区四区| 日韩AV无码中文一区二区| 天天综合色图| 性生活无遮挡纯毛片在线看| 操人91| 亚洲天堂无码| 国产在线综合网| 国产怡红院在线| 91处女视频在线观看| 国产精品麻豆成人AV艾秋| 国产乱伦性爱区| 亚洲四虎熟女精品| 人干人人人操人人摸| 久操精品| 久久久久久久性爱| 99精品在线| 亚洲精品久久久久久| 色九月婷婷| 亚洲欧美成人网站AAA| 日日操天天操| 超碰亚洲欧美日韩无| 国产综合网站在线播放 | 另类老少妇| 国产女人9999| 日本不卡码黄色| 国产精品网站免费| 啊好爽快点-国产一区二区三区撒尿在线-成人AV | 久久黄色视频一区二区三区| 亚洲欧美色图小说| 国产免a费看黄片在线| 色网在线视频观看免费| 国产操偷| 亚洲日本韩国在线| 国产999精品久久久久久| 性在久久久久久| 亚洲色图殴美色图激情乱伦| 国产精品香蕉热久久新品| 亚洲成人综合在线| 亚洲av无码成人精品国产| 亚洲精品影视老司机| 久久久精品国产亚洲AV无码| 国产精品色| 中文字幕视频在线观看一区二区| 久久九七| 97精品视频在线| 一级免费精品| 97免费视频在线观看| 日韩精品一区二区高清| 91天堂色男人的天堂| 久久久爆乳翘臀一线天伦理视频| 精品91摸| 一本大道久| 日本视频在线中文字幕| 操逼国产免费| 激情开心五月天| 少妇天堂网络| 天天综合中文字幕 91| 中文字幕精品一区二| 福利在线黄片| 久久精品一区| 黑人精品欧美一区二区蜜桃| 日韩啊V| 激情网色| 校园春色之综合网| 天欧美在线| 久久精品人妻一区| 色婷婷小说| 在线观看A啊啊啊| 2017,超碰| 日韩人妻制服丝袜av| 五月丁香亭亭| 午夜精品久久久久久久| 欧美综合自拍| 日本黄 R色 成 人网站| 神马久久久久久久久久| 色狠狠综合噜一二三区| 亚洲小说视频| 亚洲精品美女久久久久久久久| 老女人日韩美91| 激情内射| 中文字幕日韩专区精品系列 | 亚洲综合色网| 国产精品3| 成人性爱视频在线看| 精品熟女一区=区三区| 男人天堂无码| 成人 日本A片无码8888| 大香蕉 222| 超碰九7| 国产CHASE男男GAYGA 毛多色婷婷| 亚洲天堂综合AV| 欧美日韩亚洲少妇寂寞影院正在播放 | 强奸熟女一区二区三区| 夜草网站| 亚洲国产欧美日韩人妻日中文| 久久久三区二区一区| 午夜一区二区三区国产| 国产大片精久久久久久| 青草成人免费视频一com| 熟女乱伦二区| 91美女视频电影| AV无码久久久精品| 少妇99| 成人性爱视频在线看| 亚洲AV小说| 97在线观| 不卡九肏| 国产丝袜欧美在线视频| 欧美熟女激情| 国产亚洲深夜激情| 97一本大道亚洲一区| 蜜乳Av成人片网站| 青青青艹在线视频| 日韩操啪| 97超碰逼| 嗯啊抽插大香蕉网页| 欧美亚洲AN| 美国人人操人人操| 久久久精品视频欧州站| 亚洲五月天激情| 欧美翘臀视频网站一区二区三区| 精品色色| 天操天操夜操夜月操月年年操操| 夜间福利片1000无码| 狠狠躁伊人中文字幕| 婷婷五月天av| 日韩欧美性爱电影在线观看| 天堂日本亚洲欧美| 欧美日本中字另类在线| 尤物视频偷拍免费| 日韩av乱伦| 国产剧情在线| 欧美超碰96| 亚洲精品熟妇1区2区3区。| 亚洲无码国产探花在线观看| 日韩久久.一级黄色片| 人人乐大香蕉| 综合伊人网12色| 无码9区| 欧美精品97| 熟妇熟女一区二三区| 日韩无码a片| 啊啊啊啊嗯嗯嗯用力好爽 | 三级片网站在线播放| 久久久久女教师免费一区 | 久午视频| 亚洲日韩青青草色月| 亚洲第一黄色av网站| 97资源站国产精品| 嗯嗯啊啊操死我| 亚洲高清视频在线免费观看| 91在线/欧洲| 人人摸人人干| 成 人片 黄色大片| 91大香蕉伊人| 久久綜合很很很| 强奸乱亚洲| 美女久久久| 中文字幕文字幕无码一区二区三区电影99| 黄色av一区二区在线| 啪啪综合网| 老鸭窝日丰县女人| 91在线美女| 国产动漫操逼视频| dy888午夜老子影视达达兔 | 一级婬片120分钟试看| 黄色一区三区| 青青草白白色| 中文字幕在线24| 亚洲中文国际强奸字幕| 精品少妇一区二区| 91丝袜美腿网站| 国产成人无码网站在线视频| WWW操逼| 91老司机在线| 亚洲丝袜99| 国产视频一区二区三区久久亚洲天堂| 欧美亚洲日本视频久久久| 探花视频免费观看国产专区| 精品久久九| 日韩av熟女一区二区三区成人| 不卡啪啪视频| 97在线视频观看网站| 啊啊啊啊网站| 欧美精品97| 综合网少妇| 成人久久久精品| 校园春色综合| 国内91熟女人妻丝袜天天精品视频在线| 伊人久久大香线蕉无码| 欧美欧美啪啪视频| 久久精品一区二区三区四区五区| 亚洲色图欧美色图在线播放| 欧美天堂第二区| 99久久久无码| 精品精品精品| 日韩无码黄色片| 国产一级高跟丝袜| 日韩无码视频黄色| 91丝袜在线观看| 精品熟女呻吟久久91| 91色欧美| 国际精品久久久| 91综合网在线| 久久久青青草| 992视频一区| 午夜啊啊| 欧美日韩久久精品爱爱| …中文字幕亚洲乱,97人妻无码费视… | 亚洲极品| 久久久久96| 伊人视频| 欧美专区17页| 伊人伊人LD| 亚洲欧美91√| 久久精品人妻一区二区| 九九九九免费高| 美女AV一区二区| 欧美91网站| 亚洲超碰综合网| 欧美人妻另类在线| 麻豆成人影音在线| 91熟女视频| 无码一区免费在线不卡| site:sinbotex.com| 成人线上超碰| 免费福利视频中文字幕| 不卡av在线中文字幕| 欧美,日韩综合久久| 强奸乱伦av电影| 亚洲va有码在线天堂| jizzjizz欧美| 亚洲 欧美 91| AV老汉| 色综合99999| 久久久久久久六六| 情色大香蕉| 国产99999| 欧美在线永久天堂| 久久欧美性爱视频| 嗯啊不要在线观看嗯啊| 亚射在线| 久久精品高清无码一区| 激情欧美97| 日韩字幕一区| 欧美性巨大╳╳╳╳╳高跟鞋| 午夜电影在线观看无码专区| 麻豆天美国美国产AV| 熟女自慰久久久| 东方亚洲在线操逼天堂| 97jingpin| 亚洲欧美首页| 亚洲欧美日韩二区视频| 国产精品视频精品一二| 另类小说五月天| 夜夜高潮夜夜爽| 97久久国产精品| 亚洲日韩精品一区二区| 色乱二区| 中日无幕一二三四区| 九九热精彩视频| 国产综合日韩伦理| 久久一区二区三区入口| 啪啪91| 加勒比海成人视频网| 日韩精品亚洲一二三| 日韩精品一区二区高清| 91久久久久久| 性色高清..……| 精品国产av一区二区三区四区入口| 日韩一区二区高清在线观看的| 99国产精品在线观看| 久久久性爱视频| 91第一页| 无码精品一区二区三区潘金莲| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 五月婷婷色| 激情四射熟女丝袜| 午夜福利国产欧美日韩夜夜| 人人妻人射| 日韩中文字幕2020| 国产性爱强奸乱伦大全| 久久久中文| 人妻无码视频一区二区三区久久| 激情文学88| AV天天在线观看| 91制服丝袜| 亚洲欧美日韩精品久| 狠狠爱夜夜干| 操逼片国产| 久久精品亚洲东京热色播| 精品99999| 天天日天天插| 久久精品—区二区三区内射| 久久香蕉综合一本到3atv| 亚洲少妇激情视频| 中文字幕一区二区三区高清| 日韩二级| 国产精品午夜AV完会免费| 国产久久一区二区午夜| 人妻无码一区二区三区久久99| 无码高清操逼网址| 少妇内射www在线观看视频| 综合av社区| 蜜奶av| 亚洲免费在线探花| 最新精品久久蜜桃 | 精品无码一二三四区| 99久久亚洲精品无码毛片潘甜甜| 欧苏综合色综合| 天天日熟妇| 爆操无码| 国产中文字幕在线观看| 欧美性爱视频免费一区一A| 欧美人人天天网| 操逼视频亚洲| 色偷偷色偷偷欧美日韩| 在线无码操| 蜜乳av一区二区三区| 特级丰满少妇一级AAAA爱毛片| 青草视频人妻在线观看| 综合免费无码中文| 91美女视频电影| 亚欧无码在线| 久久老熟女| 亚洲性爱高潮影院| 欧美天天性| 97在线观视频免费观看| 国产黄色 A 片免费看| 欧美日韩97在线| 国模限制级电影| 亚洲综合首页| 欧美少妇第一页| 95自拍视频在线观看| 东京热大香焦| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 97超碰碰碰| 亚洲一区二区三区在线激情| 欧亚久久偷拍视频| 97人人模人人爽人人| 亚洲色宗合| 久久中出在线| 欧美日韩999| 粉嫩av在线| 综合91网| 国产黄a三级三级三级av在线看| 国产91亚洲精品一区二区三区| 青娱乐 成人娱乐在线| 欧美少妇性爱网站| 中文字幕一区二区三区四五区| 欧美中出1| 免费av在线播放二区| 久久精品99| 伊人色综合网电影| 欧美伊人久久综合网| 女人18精品一区二区三区| 992这里有精品| 在线观看免费视频国产| 日韩射图| 成人片视频| 亚洲精品一区中文字幕乱码| 久久午夜鲁丝片| 欧美人妻制服| 91日产欧美| 骚逼高潮久久精品| 强奸乱伦日韩AV| 亚洲欧美999| 粉嫩少妇自慰在线| 五月天成人综合| 不卡av在线中文字幕| 国产精品69久久久久孕妇欧美| 天天肏夜夜肏| 中文字幕在线观看永久| 亚洲色图 图片| 国产天美欧美| 熟女突然公开看18禁影片| 乱伦1色页| 呦呦一区| 日本不卡一区二区三区| 青娱乐蜜桃臀AV色婷| 长长久久88视频| 久久98| 91久久精品中文字幕| 超碰色综合| 九热中文字幕| 中出人妻中文字幕91在线| www.99热| 欧美麻豆成人同性GⅤ在线| 久久国产逼| 91久久九九精品国产综合| 香蕉99秘 一区精品蜜桃臀| 日韩精品99久久久久久中文字幕| 色婷婷亚洲婷婷| 91男人天堂网| 亚洲日产专区| 免费看日产一区二区三区| 亚欧成人综合影院| 精品国产91av一区二区三区| 国产v亚洲v日韩v欧美v片另类| 人人澡人人澡人人| 国产蜜臀在线| 国产和美国毛片| 精品一区二区三区蜜桃臀赵总 | 女同亚洲欧美一二三区久久电影| 国产情侣自拍在线播放| 无码最新| 日操粉逼逼| 日韩精品国产一区二区| 中国农村熟妇毛片视频| 性饥渴少妇av无码毛片| 无码一区免费在线不卡| 99re视频在线播放青草| 啊啊啊轻点在线观看| 国产风韵犹存熟妇三区| 另类av天堂| 艳尻美人妻| 啊啊啊97视频| 日韩性色b|