亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

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

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

Spring事務(wù)失效的7個(gè)坑與底層原理:從JDBC到分布式事務(wù) 1. 事務(wù)失效的七宗罪我踩過(guò)的坑你大概率也會(huì)踩先講個(gè)真實(shí)事故。幾年前我維護(hù)過(guò)一個(gè)電商訂單系統(tǒng)線(xiàn)上出了一個(gè)詭異的bug用戶(hù)支付成功后訂單狀態(tài)正常更新但庫(kù)存卻莫名其妙多扣了一次。代碼看起來(lái)完全沒(méi)問(wèn)題——service方法上明明白白標(biāo)著Transactional數(shù)據(jù)庫(kù)也確認(rèn)是InnoDB。查了兩天才定位到根因同一個(gè)類(lèi)里方法A調(diào)用方法BB的事務(wù)注解根本沒(méi)生效。這就是Spring事務(wù)最經(jīng)典的坑之一自調(diào)用繞過(guò)代理。Transactional依賴(lài)AOP代理生效而Spring的代理機(jī)制決定了一個(gè)類(lèi)內(nèi)部的方法調(diào)用是不會(huì)經(jīng)過(guò)代理對(duì)象的。this.orderService.update()拿到的這個(gè)this根本不是Spring容器里那個(gè)被代理過(guò)的bean而是原始對(duì)象。原始對(duì)象上的注解Spring根本看不見(jiàn)。結(jié)果就是你以為開(kāi)啟了事務(wù)實(shí)際上沒(méi)有。庫(kù)存扣減在無(wú)事務(wù)狀態(tài)下執(zhí)行訂單那邊一旦報(bào)錯(cuò)回滾庫(kù)存早就提交了。1.1 自調(diào)用問(wèn)題最隱蔽的事務(wù)殺手自調(diào)用這個(gè)坑的隱蔽之處在于它不會(huì)報(bào)錯(cuò)不會(huì)警告日志里什么都看不出來(lái)只有數(shù)據(jù)對(duì)不上賬的時(shí)候才會(huì)暴露。Service public class OrderService { Transactional public void createOrder(OrderDTO dto) { // 扣庫(kù)存 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完全無(wú)效。因?yàn)閠his.sendNotification()走的是原始對(duì)象不是代理。解決辦法有三個(gè)把需要事務(wù)的方法挪到另一個(gè)Service類(lèi)——最推薦職責(zé)也最清晰。注入自身代理Autowired private OrderService self;然后調(diào)用self.sendNotification()。使用AopContext.currentProxy()需要開(kāi)啟EnableAspectJAutoProxy(exposeProxy true)然后((OrderService) AopContext.currentProxy()).sendNotification()。方案2最實(shí)用但要注意循環(huán)依賴(lài)問(wèn)題——Spring 4.3之后字段注入的循環(huán)依賴(lài)是允許的但構(gòu)造器注入就不行。方案3代碼看著別扭但確實(shí)有效。1.2 非public方法注解白寫(xiě)了Transactional用在private或者protected方法上Spring容器啟動(dòng)時(shí)根本不報(bào)錯(cuò)但方法執(zhí)行時(shí)事務(wù)就是沒(méi)開(kāi)。原理不復(fù)雜Spring AOP生成代理的時(shí)候JDK動(dòng)態(tài)代理基于接口只代理public方法CGLIB雖然能代理非public方法但Spring官方明確說(shuō)了Transactional只支持public方法。最騷的是如果你把Transactional放在public方法上、但里面調(diào)用了private方法private方法里的事務(wù)注解同樣無(wú)效——因?yàn)槭聞?wù)邊界已經(jīng)在public方法的代理上確定了內(nèi)層調(diào)用不會(huì)再開(kāi)啟新事務(wù)除非傳播行為是REQUIRES_NEW。我見(jiàn)過(guò)不少項(xiàng)目把Transactional加到private方法上然后一臉疑惑地說(shuō)為什么回滾了沒(méi)生效。排查方法很簡(jiǎn)單看日志里有沒(méi)有TransactionInterceptor的getTransaction記錄沒(méi)有就是代理沒(méi)走。1.3 異常被吞回滾了個(gè)寂寞這是最常見(jiàn)也最無(wú)語(yǔ)的一種。Java的檢查型異常checked exception默認(rèn)不會(huì)觸發(fā)Spring事務(wù)回滾但很多人不知道這一點(diǎn)隨手寫(xiě)了個(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)不通過(guò)拋了個(gè)業(yè)務(wù)異常 throw new BizException(余額不足); }BizException如果是繼承Exception而不是RuntimeException上面這個(gè)事務(wù)不會(huì)回滾錢(qián)就憑空消失了。Spring的默認(rèn)回滾策略是只回滾RuntimeException和Error。檢查型異常如IOException不會(huì)觸發(fā)回滾因?yàn)镾pring認(rèn)為你既然顯式聲明了這個(gè)異常說(shuō)明你可以處理它事務(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上寫(xiě)rollbackFor Exception.class。雖然看起來(lái)冗余但團(tuán)隊(duì)里總有人會(huì)寫(xiě)檢查型異常。1.4 多線(xiàn)程子線(xiàn)程異常主線(xiàn)程事務(wù)照樣提交Transactional的事務(wù)上下文存在ThreadLocal里子線(xiàn)程拿不到父線(xiàn)程的事務(wù)上下文。Transactional public void batchProcess(ListOrder orders) { orders.parallelStream().forEach(order - { // 這里拋異常父線(xiàn)程事務(wù)不會(huì)感知 processOne(order); }); }如果一定要在多線(xiàn)程里用事務(wù)只能每個(gè)線(xiàn)程自己開(kāi)事務(wù)用TransactionTemplate包住子線(xiàn)程的任務(wù)代碼然后在線(xiàn)程池層面做異常聚合——子線(xiàn)程里有任何失敗主線(xiàn)程如何決定是否整體回滾需要自己實(shí)現(xiàn)協(xié)調(diào)邏輯。這個(gè)問(wèn)題在批量導(dǎo)入、報(bào)表生成、定時(shí)任務(wù)場(chǎng)景里非常常見(jiàn)。我的建議是批量任務(wù)盡量不用Transactional包整段而是每條或每批用TransactionTemplate單獨(dú)開(kāi)事務(wù)配合失敗記錄表做補(bǔ)償。這樣既能保證數(shù)據(jù)一致又不會(huì)因?yàn)橐粋€(gè)線(xiàn)程失敗導(dǎo)致大批量回滾。1.5 數(shù)據(jù)庫(kù)引擎不支持事務(wù)這個(gè)坑現(xiàn)在少了但老項(xiàng)目中還能見(jiàn)到。MySQL的MyISAM引擎根本不支持事務(wù)你注解標(biāo)得再多也沒(méi)用。確認(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類(lèi)或final方法CGLIB也救不了Spring事務(wù)默認(rèn)用AOP代理。如果目標(biāo)類(lèi)配置了JDK動(dòng)態(tài)代理基于接口那沒(méi)問(wèn)題如果走CGLIB基于類(lèi)繼承生成子類(lèi)那么final類(lèi)無(wú)法被繼承final方法無(wú)法被重寫(xiě)代理自然失效。Spring Boot 2.x之后默認(rèn)proxyTargetClasstrue走CGLIBfinal問(wèn)題就浮出水面了。很多人把service類(lèi)寫(xiě)成final為了防繼承結(jié)果事務(wù)全失效。排查方法啟動(dòng)時(shí)看日志里是JdkDynamicAopProxy還是CglibAopProxy再看你的類(lèi)和方法有沒(méi)有final修飾符。1.7 事務(wù)管理器沒(méi)配置或配置錯(cuò)了Spring Boot的DataSourceAutoConfiguration會(huì)自動(dòng)配置DataSourceTransactionManager但你如果引入了多數(shù)據(jù)源或者自定義了DataSource而沒(méi)有配套注冊(cè)PlatformTransactionManager那Transactional就會(huì)失效。另外EnableTransactionManagement注解在Spring Boot里默認(rèn)開(kāi)啟不需要你重復(fù)添加。但如果你用了Spring MVC非Boot項(xiàng)目忘了加EnableTransactionManagement事務(wù)也會(huì)靜默失效。排查清單很簡(jiǎn)單Transactional方法執(zhí)行的線(xiàn)程棧里有沒(méi)有TransactionInterceptor有就是代理生效了沒(méi)有就是代理沒(méi)生效。2. Spring事務(wù)的底層運(yùn)作機(jī)制從JDBC到動(dòng)態(tài)代理很多人用Transactional用了好幾年但完全不知道它背后發(fā)生了什么。面試被問(wèn)Spring事務(wù)是怎么實(shí)現(xiàn)的只會(huì)答AOP兩個(gè)字就再也說(shuō)不出更多了。其實(shí)底層鏈路沒(méi)那么玄拆開(kāi)看就三層JDBC的事務(wù)能力、Spring的事務(wù)抽象、AOP的代理包裝。2.1 第一層JDBC的事務(wù)基石萬(wàn)事萬(wàn)物都離不開(kāi)JDBC。Spring事務(wù)再花哨落到底層就是這三行代碼Connection conn dataSource.getConnection(); conn.setAutoCommit(false); // 關(guān)閉自動(dòng)提交 conn.commit(); // 提交 conn.rollback(); // 回滾setAutoCommit(false)的意思是之后的SQL不會(huì)立即生效必須等commit()才真正寫(xiě)入數(shù)據(jù)庫(kù)MySQL的binlog和redolog層面是另一套機(jī)制。如果中途異常調(diào)用rollback()之前的所有操作全部撤銷(xiāo)。所以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ì)檢查T(mén)ransactionStatus里的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)閉它并記下來(lái)方便事務(wù)結(jié)束恢復(fù)。設(shè)置隔離級(jí)別如果TransactionDefinition指定了。設(shè)置只讀標(biāo)志readOnlytrue會(huì)走Connection.setReadOnly對(duì)MySQL的InnoDB來(lái)說(shuō)這能優(yōu)化一些查詢(xún)路徑。把這個(gè)Connection綁定到TransactionSynchronizationManager的ThreadLocal里。后面的DAO操作拿到的Connection就是從TransactionSynchronizationManager里取的。這就是同一個(gè)事務(wù)里所有SQL共用同一個(gè)數(shù)據(jù)庫(kù)連接的原理——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ù)就開(kāi)多久。2.4 只讀事務(wù)與UnexpectedRollbackException的真相熱詞里有一條UnexpectedRollbackException: transaction rolled back because it has been marked as rollback-only這是個(gè)非常經(jīng)典的問(wèn)題。場(chǎng)景是這樣的方法A開(kāi)啟事務(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ù)回滾。換句話(huà)說(shuō)你代碼里沒(méi)拋異常但事務(wù)已經(jīng)注定要回滾了。這經(jīng)常出現(xiàn)在try-catch吃了異常但沒(méi)重新拋出的情況下。排查時(shí)看日志里有沒(méi)有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做嵌套背下來(lái)容易用對(duì)難。我把這幾個(gè)傳播行為逐個(gè)講透配上真實(shí)場(chǎng)景你就能理解了。3.1 傳播行為詳解Spring定義了7種傳播行為大部分項(xiàng)目用到的不超過(guò)4種但理解每一種的原理仍然重要。傳播行為含義典型場(chǎng)景REQUIRED有事務(wù)就復(fù)用沒(méi)有就新建默認(rèn)值99%的場(chǎng)景用它SUPPORTS有事務(wù)就加入沒(méi)有就無(wú)事務(wù)執(zhí)行查詢(xún)方法可選MANDATORY必須在事務(wù)中執(zhí)行否則拋異常強(qiáng)制事務(wù)的方法REQUIRES_NEW掛起當(dāng)前事務(wù)永遠(yuǎn)新建一個(gè)寫(xiě)日志、異步通知NOT_SUPPORTED掛起當(dāng)前事務(wù)以無(wú)事務(wù)方式執(zhí)行導(dǎo)出大數(shù)據(jù)量文件NEVER如果有事務(wù)就拋異常強(qiáng)制無(wú)事務(wù)的執(zhí)行NESTED嵌套事務(wù)基于保存點(diǎn)Savepoint大批量循環(huán)處理單條失敗不影響整體REQUIRED是默認(rèn)值理解起來(lái)很簡(jiǎn)單Spring檢查當(dāng)前ThreadLocal里有沒(méi)有綁定事務(wù)有就加入沒(méi)有就新建一個(gè)。注意加入意味著共用一個(gè)事務(wù)、一個(gè)Connection、一套commit/rollback。內(nèi)層方法拋異常回滾外層也一起回滾。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ù)方法開(kāi)啟事務(wù)日志記錄要獨(dú)立提交——不管業(yè)務(wù)成功還是失敗日志都要寫(xiě)進(jìn)去。如果你用REQUIRED業(yè)務(wù)回滾時(shí)日志也跟著回滾那排查問(wèn)題的時(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ù)庫(kù)支持保存點(diǎn)。MySQL的InnoDB支持但有些數(shù)據(jù)庫(kù)不支持且JpaTransactionManager對(duì)NESTED的支持有限。實(shí)際項(xiàng)目中能用REQUIRES_NEW解決的就別用NESTED少踩坑。3.2 隔離級(jí)別臟讀、不可重復(fù)讀、幻讀Spring事務(wù)隔離級(jí)別有五種對(duì)應(yīng)JDBC的隔離級(jí)別隔離級(jí)別臟讀不可重復(fù)讀幻讀說(shuō)明DEFAULT---使用數(shù)據(jù)庫(kù)默認(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)兩次查詢(xún)返回的記錄數(shù)不一樣因?yàn)閯e的事務(wù)插入了新記錄。MySQL的InnoDB在REPEATABLE_READ級(jí)別下通過(guò)MVCC多版本并發(fā)控制 Gap Lock間隙鎖實(shí)際上消除了幻讀問(wèn)題。所以MySQL默認(rèn)的REPEATABLE_READ比Oracle的READ_COMMITTED在某些場(chǎng)景下更嚴(yán)格。實(shí)際項(xiàng)目中我見(jiàn)過(guò)很多團(tuán)隊(duì)把隔離級(jí)別統(tǒng)一設(shè)成READ_COMMITTED理由是MySQL的RR有間隙鎖并發(fā)插入容易死鎖。這個(gè)說(shuō)法有一定道理但不是絕對(duì)的。如果你的系統(tǒng)沒(méi)有復(fù)雜的范圍查詢(xún)并發(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ù)開(kāi)始到最后一次SQL執(zhí)行的時(shí)間不是方法總耗時(shí)。如果你的方法在事務(wù)前做了一堆耗時(shí)操作比如遠(yuǎn)程調(diào)用這部分不計(jì)入事務(wù)超時(shí)。所以不要指望timeout能保護(hù)整體方法執(zhí)行時(shí)間。關(guān)于回滾策略我再?gòu)?qiáng)調(diào)一次// 推薦寫(xiě)法 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ù)用起來(lái)方便但有三個(gè)致命弱點(diǎn)事務(wù)粒度太大整個(gè)方法一個(gè)事務(wù)如果方法里有網(wǎng)絡(luò)調(diào)用或批量循環(huán)事務(wù)會(huì)長(zhǎng)時(shí)間占用數(shù)據(jù)庫(kù)連接。自調(diào)用失效前面已經(jīng)講過(guò)了。無(wú)法精確控制提交時(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)里你可以在任何地方開(kāi)啟事務(wù)塊粒度完全由自己控制。更重要的是它徹底繞開(kāi)了自調(diào)用問(wèn)題——因?yàn)槟闶侵苯诱{(diào)用事務(wù)管理器不走代理。還有一個(gè)場(chǎng)景強(qiáng)烈推薦用TransactionTemplate大批量循環(huán)插入。如果用Transactional包住整個(gè)for循環(huán)幾萬(wàn)條數(shù)據(jù)一個(gè)事務(wù)提交時(shí)數(shù)據(jù)庫(kù)壓力巨大一旦失敗全部回滾代價(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); // 開(kāi)啟新事務(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ù)代碼里寫(xiě)這種底層代碼——容易出錯(cuò)而且代碼很難讀。99%的場(chǎng)景TransactionTemplate夠用了。4.3 編程式事務(wù)的注意點(diǎn)TransactionTemplate是線(xiàn)程安全的可以做成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ù)跳出單庫(kù)思維的邊界單庫(kù)單事務(wù)的好日子總有到頭的時(shí)候。微服務(wù)一拆、分庫(kù)一搞Transactional就管不住跨庫(kù)的數(shù)據(jù)一致性了。我先講清楚Spring事務(wù)在多數(shù)據(jù)源下的表現(xiàn)再展開(kāi)分布式事務(wù)。5.1 多數(shù)據(jù)源下的事務(wù)各管各的如果你配置了兩個(gè)DataSource比如一個(gè)主庫(kù)一個(gè)從庫(kù)Spring里注冊(cè)了對(duì)應(yīng)的兩個(gè)PlatformTransactionManager同一個(gè)Transactional方法里操作了兩個(gè)庫(kù)——那這兩個(gè)庫(kù)的事務(wù)是互相獨(dú)立的。主庫(kù)提交成功、從庫(kù)提交失敗你沒(méi)有任何辦法通過(guò)單機(jī)事務(wù)解決。Spring Boot里處理多數(shù)據(jù)源的常規(guī)姿勢(shì)是Transactional(transactionManager xxxTransactionManager)指定用哪個(gè)事務(wù)管理器。方法里操作另一個(gè)庫(kù)那份數(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è)大話(huà)題我只挑主流方案講給個(gè)選型思路。XA協(xié)議兩階段提交2PCXA是最正統(tǒng)的分布式事務(wù)協(xié)議分兩步準(zhǔn)備階段所有參與者執(zhí)行SQL但不提交各自保留Undo/Redo log和提交階段協(xié)調(diào)者發(fā)提交指令各參與者提交。問(wèn)題在于準(zhǔn)備階段會(huì)一直持有數(shù)據(jù)庫(kù)鎖高并發(fā)場(chǎng)景下鎖沖突嚴(yán)重性能非常差。Java里典型的實(shí)現(xiàn)是Atomikos、Bitronix。說(shuō)實(shí)話(huà)互聯(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ù)都要寫(xiě)三套邏輯。典型場(chǎng)景賬戶(hù)轉(zhuǎn)賬。Try階段凍結(jié)轉(zhuǎn)出金額Confirm階段扣款Cancel階段解凍。這個(gè)方案需要深入理解業(yè)務(wù)才能寫(xiě)得對(duì)如果你只是想快速實(shí)現(xiàn)一個(gè)分布式事務(wù)TCC的學(xué)習(xí)成本挺高的。消息事務(wù) 最終一致性這是目前最常用、成本最低的方案。思路很簡(jiǎn)單利用本地事務(wù)把業(yè)務(wù)操作和發(fā)消息綁定在同一次數(shù)據(jù)庫(kù)事務(wù)里通過(guò)消息中間件RocketMQ/RabbitMQ最終把數(shù)據(jù)變更同步給其他服務(wù)。舉個(gè)訂單和積分的例子開(kāi)啟本地事務(wù)插入訂單表同時(shí)插入積分消息表。本地事務(wù)提交后后臺(tái)任務(wù)或MQ的事務(wù)消息機(jī)制把積分消息表里未發(fā)送的記錄發(fā)到MQ。積分服務(wù)從MQ消費(fèi)消息給用戶(hù)加積分。如果積分服務(wù)失敗消息進(jìn)入重試隊(duì)列直到成功。這種方案做不到強(qiáng)一致中間會(huì)有一段數(shù)據(jù)不一致的時(shí)間窗口但絕大多數(shù)業(yè)務(wù)都能接受。核心機(jī)制是本地消息表實(shí)現(xiàn)成本低、不用引入重量級(jí)中間件是目前國(guó)內(nèi)互聯(lián)網(wǎng)公司的首選方案。Seata的AT模式Seata是阿里開(kāi)源的分布式事務(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ù)庫(kù)什么都不用本地事務(wù)夠用微服務(wù)對(duì)一致性要求不高本地消息表 MQ最終一致微服務(wù)強(qiáng)一致要求高Seata AT 或 TCC金融級(jí)強(qiáng)一致低并發(fā)XA/2PC非核心數(shù)據(jù)可以容忍短暫不一致MQ異步 對(duì)賬補(bǔ)償分布式事務(wù)沒(méi)有銀彈。選型的核心不是哪個(gè)方案高級(jí)而是你的業(yè)務(wù)能容忍多大程度的不一致。6. 事務(wù)排查工具箱從日志到監(jiān)控的一整套姿勢(shì)事務(wù)的問(wèn)題一旦出現(xiàn)往往都是線(xiàn)上的、隱性的、難復(fù)現(xiàn)的。所以一定要有一套預(yù)防和排查的手段而不是等出了問(wèn)題再手忙腳亂。6.1 日志配置把事務(wù)邊界打印出來(lái)Spring的事務(wù)日志默認(rèn)是DEBUG級(jí)別不打開(kāi)根本看不到。在application.yml里配置logging: level: org.springframework.transaction: DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager: DEBUG org.springframework.jdbc.datasource.JdbcTransactionManager: DEBUG打開(kāi)后你會(huì)看到類(lèi)似這樣的日志Obtained JDBC transaction from DataSource [HikariDataSource (HikariPool-1)] Participating in existing transaction Initiating transaction commit Initiating transaction rollback這些日志的排列能幫你快速判斷事務(wù)有沒(méi)有開(kāi)啟、是新建還是復(fù)用、提交還是回滾、有沒(méi)有因?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說(shuō)明當(dāng)前線(xiàn)程確實(shí)有數(shù)據(jù)庫(kù)事務(wù)處于活動(dòng)狀態(tài)。如果外面標(biāo)了Transactional但這里返回false說(shuō)明代理沒(méi)生效——自調(diào)用、final方法、私有方法逐個(gè)排查。還可以查看當(dāng)前事務(wù)名Object name TransactionSynchronizationManager.getCurrentTransactionName();這能幫你快速定位當(dāng)前事務(wù)是哪個(gè)方法開(kāi)啟的。6.3 監(jiān)控事務(wù)耗時(shí)與連接占用事務(wù)另一個(gè)容易忽略的問(wèn)題是連接泄漏和長(zhǎng)事務(wù)。一個(gè)事務(wù)如果執(zhí)行了幾十秒連接就占用了幾十秒連接池很快被打滿(mǎn)。建議做法在DataSource層加慢SQL日志HikariCP有connectionTimeout、validationTimeout配置同時(shí)開(kāi)啟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í)過(guò)長(zhǎng): {}ms, status{}, cost, status); } } }); }這個(gè)方法能精確定位哪個(gè)事務(wù)方法最耗時(shí)但它需要每一個(gè)業(yè)務(wù)方法都加一遍侵入性強(qiáng)。更好的方案是寫(xiě)一個(gè)AOP切面統(tǒng)一攔截Transactional方法做耗時(shí)統(tǒng)計(jì)。6.4 事務(wù)失效排查的標(biāo)準(zhǔn)操作流程如果線(xiàn)上出現(xiàn)了疑似事務(wù)失效的問(wèn)題我的排查順序是這樣的看日志打開(kāi)事務(wù)DEBUG日志確認(rèn)方法執(zhí)行時(shí)有沒(méi)有Obtained JDBC Transaction記錄。沒(méi)有就是代理沒(méi)生效走第2步有就繼續(xù)看提交/回滾記錄走第5步??捶椒ê灻遣皇莗ublic類(lèi)或方法有沒(méi)有final看調(diào)用方是不是同一個(gè)類(lèi)內(nèi)部調(diào)用是不是沒(méi)有被Spring管理的對(duì)象比如new出來(lái)的看注解Transactional有沒(méi)有寫(xiě)對(duì)rollbackFor有沒(méi)有配多數(shù)據(jù)源下transactionManager指對(duì)了沒(méi)有看異常異常有沒(méi)有被try-catch吞掉異常類(lèi)型是不是RuntimeException看數(shù)據(jù)庫(kù)表引擎支不支持事務(wù)連接是不是走到了正確的DataSource這套流程走一遍90%的事務(wù)問(wèn)題都能定位。7. 最后的實(shí)戰(zhàn)建議事務(wù)規(guī)范從我做起寫(xiě)到這里我把這些年跟事務(wù)打交道沉淀下來(lái)的幾條規(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ù)庫(kù)操作移到事務(wù)外或者拆成多個(gè)事務(wù)塊。事務(wù)邊界要盡可能晚開(kāi)啟盡可能早提交。前置校驗(yàn)、參數(shù)組裝這些放事務(wù)外真正需要數(shù)據(jù)庫(kù)原子性的操作才放進(jìn)事務(wù)塊。很多人習(xí)慣方法一進(jìn)來(lái)就開(kāi)事務(wù)其實(shí)很多操作根本不需要事務(wù)保護(hù)。回滾配置要顯式寫(xiě)。Transactional(rollbackFor Exception.class)這行字雖然啰嗦但它能擋住95%的回滾失效問(wèn)題。自定義的業(yè)務(wù)異常統(tǒng)一繼承RuntimeException省得每個(gè)方法都要考慮這個(gè)異常會(huì)不會(huì)回滾。批量處理用TransactionTemplate而不是Transactional。循環(huán)里的事務(wù)一定要用編程式事務(wù)精確控制粒度Transactional包整個(gè)循環(huán)就是把數(shù)據(jù)庫(kù)往死里逼。分布式事務(wù)不要貪多求全。能靠業(yè)務(wù)流程設(shè)計(jì)規(guī)避的就盡量規(guī)避比如通過(guò)本地消息表做最終一致性比引入一套重量級(jí)分布式事務(wù)框架劃算得多。選型之前先想清楚你的數(shù)據(jù)不一致容忍度。事務(wù)這個(gè)東西說(shuō)到底是數(shù)據(jù)庫(kù)連接和錯(cuò)誤處理時(shí)機(jī)的管理藝術(shù)。理解底層機(jī)制比背多少面試題都管用。希望這篇文章里踩過(guò)的坑、總結(jié)的思路能讓你少走幾條彎路。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
成人一区二区三区四区| 91丨人妻丨国产丨丝袜| 亚洲一级性爱视频免费看| 亚洲网污污污污| 日本亚洲熟女视频| 91艹B视频| 加勒比99999| 五月天久久婷婷亚洲 | 尤物视频一区| 91人妻在线视频| 91日产欧美| 免费一级毛片在线视频观看| 欧美在线视频观看一二三四区高清| 亚洲欧美在线观看2021| 国产乱色国产精品免费视| 日韩91网| 男女性扦B| 上床不卡网站| 日韩中文字幕2020| 欧美熟妇精品黑人巨大一二三区| 狠狠色丁香| 亚洲成av人片色午夜乱码| 最新无码国产| 丰满美女一级毛片在线播放| 熟妇综合一区二区三区| 熟女熟妇一区二区三四区 | 人妻精品一区二区| 七月婷婷综合| 放黄片放3级黄片没穿衣服| 国产一线二线三线av| 欧亚日韩综合精品国产| 91欧美情色| 78精品在线| 操逼无毒无码免费视频| 成人性爱免费播放| 日韩性爱1级片视频| 国产精品免费1区2区视频| 超碰精品日韩欧美国产| 超碰国产精品无码| 日本一区二区不卡精品| 丁香九月激情| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 99久久久久久亚洲精品不卡| 国产日韩色综合| 欧美精品23| 国产家庭乱伦表演| 天天草夜夜草高潮片| 9久在线视频只有精品| 91A欧美电影网站| 操久久久久| 天堂亚洲精品| 国产 日韩,欧美 自拍| 欧美劲爆第一页| 日韩色香| 成人在线日韩| 欧美se亚洲| 最新av在线| 欧美熟女逼久久久久久| 少妇精品久久| 国产9 9在线 | 亚洲| 日韩无码a片| 探花一区在线| 麻豆AV96熟妇人妻| 中文字幕在线第二页| 乱色老一区二区三区的观看方式| 日韩有码中文字幕女同性恋| 国产午夜精品在线观看| 911粉嫩人妻| 97人人干| 久久熟女久| 日韩91网站| 久久精品国内Av熟女高清| 国产黄片精品在线| 精品少妇后入一区二区三区四区人妻巨乳| 99色婷婷中文字幕乱色| 全国男人天堂网| 看日韩黄片| 国产第25页在线观看| 丁香六月婷婷综合| 午夜AV污污污| 美女裸体无遮挡永久免费观看网站| 天堂俺去俺来也www久久婷婷| 色色色网站| 屌妞视频久久久久久久 | 色爱三区| 9999亚洲电影| 夜草网站| 欧美色棕合| 中文字幕午夜精品久久久| 超碰97亚洲| wwwcaobibi| 亚州色图狠狠干| 蜜臀久久99精品久久久久电影| 国产 日韩,欧美 自拍| 人人操人人叉人人插人人| 久久久久成人蜜桃精品| 性综合网| 日韩一区二区精品视频| 97Ai亚洲| 啊灬啊灬啊灬好深灬快高潮了动漫-国产字幕国产在线观看-B049AV | 久久久国产精品亚洲精品| 黄页av| 中文字幕一区二区三区高清| 国产日本熟女顶级一区二区三区视频 | 免费无码婬片AAAA片直播色戒| 日韩免费中文字幕视频| 久久思思热| 亚洲男人天堂2| 无码一区免费在线不卡| 97精品视频免费| 超碰97护士| 澳门特级毛片免费观看| 神马九九九| 在线a v| 日韩ab网| 在线观看A啊啊啊| 色综合国产在线观看| 69国产对白刺激| 哑洲在线| 国产热RE99久久6国产精品首| 9精品在线| se吧提供国产乱老熟视频胖女人| 欧美亚洲影视| 翔田千里AⅤHD无码| 97超碰天天爱天天爱| 欧美组图日韩亚洲中文字幕| 天天干天天拍| 国产无码成人无码| 神马视频久久久久久| 日本不卡在线二区三区| 丁香五月天堂网| 久久精品—区二区三区内射| 在线观看一卡二卡| av一区二区三区不卡| 久久一二三级一一一| AV天堂国产| 麻豆性爱视频在线播放| 久久亚洲欧美中文字幕国语| 加勒比少妇AV婷婷六月天超碰超碰| 日韩免费福利在线观看| 欧美后入式| 天天天天操| 亚洲精品97| 精品人妻夜夜草| 在线观看亚洲专区| 男人的天堂kva| 国产天天骚| 黄色视频60分钟| 欧美日日人人天天| 97久久精品亚洲| 日韩在线国产字幕| 毛片麻豆91糖心精品毛情片| 蜜臀av一区二区三区免费观看| 久久久久久久性爱| 99热 按摩 日韩| 国产亚州高清国产拍精| 国产婷婷综合在线观看| 午夜九九| 亚洲男人天堂网久久| 无码高清国产AV| 天堂性色| 98精品国产乱码久久久久久| 92福利社视频| 亚洲国产麻豆一区二区三区| 亚洲色图欧洲| 情色五月天网| 九九热视频这里只有精品| 亚洲码专区| 强奸乱伦AV一天堂网| 国偷自 一区二区| 91neishe| 翘臀vidoes| 丁香五月综合| 久久色一区二区| 精品999日本| 艹少妇网站| 9999伦理视频| 亚洲欧美天堂在线| www.久久最新地址| 日本精品一区二区三区四区的功能| 极品内射| 久久精品视-一级做a爰片性色毛片16美国-中国女与老外在线精品 | 欧美性爱无码一区二区三区| 中文字幕国产在线天堂| 亚洲资源一区| aV中文麻| 亚洲情色 无码专区| 江都AV在线| 超碰91在线| 精品亚洲黄色片 国产精品导航一区二区| 国产精品一区二区三区四区五区| 久久久啊啊啊| 91精品国| 97色在线视频| 久久久蜜桃臀无码视频| 国产白丝网站| 91热| 躁躁躁日日躁2020| 亚洲天堂资源在线| 9久久久久久| 99精品无码| 九九九九九九免费视频| 亚洲国产蜜臀系列在线观看| 黑人精品久久97| 97欧美色资源| 性性久久| 大屁股熟女一区二区三区| 久久天天躁日日躁狠狠躁| 岛国小电影| 操人妻丝袜高跟| 夜夜爽夜夜摸夜夜操免费视频| 超碰综合色| 伊人网在线视频| 青青伊人久久| 校园春色美腿丝袜| 夜夜欧美| av东京热男人的天堂| 目产99999久久999| 国产第25页在线观看| 性色AV蜜色av色欲av| 屁股久久久久久| 精品无码久久久久久久久果冻糖心| 欧美性爱日韩性爱| 黄色视频特级毛片| 色爱国产| 性色avv| 日本一区99| 色大师网站www永久网站视频| 激情亚洲天堂| 玖玖无码超碰| 人人看人人插| 久久久国产亚洲精品系列| 综合欧美激情网| 久久久久久精品免费看A级| 亚洲国产高清福利视频| 95精品在线| 大香蕉天天看妹子| 97国产精品在线观看| 黄色工厂这里只有精品| 日人妻视频91| 欧美久久九九| 黄色一区三区| 毛片一区二区| 国产激情av女片自拍| 久久精品男人的天堂| 欧美 亚洲 在线| 亚瑟国产精品久久无码| 深爱五月天| 美骚妇av高清在线| 国产精品3| 欧美日韩国产成人高清| 日韩欧美麻豆| 国产精品久久久久久久AV大片| 91亚洲人| 神马久久久久久伦理片| 国产女上位好爽在线| 天天日天天射天天干| 蜜臀无码一区二区| 免费视频在线一区二区不卡| 丁香五月成人| 视频在线中文字幕| 国产精品直播在线观看直播| 91狼人| 亚洲熟女乱色| 9丨久久九九九| 爆操无码| 中文字幕诱惑制服人妻丝袜美丝袜美| 一区二区乱码福利| 久久午夜伦| 久久久久久少妇| 欧美一级美片在线观看免费| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 亚洲91射| 国产精品一区二区 尿失禁| 国产怡红院| 欧美激情在线观看视频| 色五月av| 熟女少妇一区二区三区| 亚洲乱码国产乱码精网站| 久久伊人网视频一区二区三区| 97超碰超| 日韩精品三区四区| 夜色91| 色99在线| 国产高清视频无码在线| 亚洲欧美九九九| 在线观看中文av字幕| 啊啊啊啊操死我了| 福利操逼| 91熟女视频网| 欧美刺激色黄片免费看| 国产精品国产| 再深点灬舒服灬太大了好硬好爽| 一本大道久| 亚洲最大无码中文字幕网站| 女上位精品在线| 午夜福利精品| 久操频道免费在线呗看| 91丝袜美女国产| 久久久一区二区三区四区五区| 午夜免费视频1000| 久久久久久99AV无码免费网站| 大香蕉伊人网WWWn0n| 男人的天堂网页| 国产原创精品| 日韩无码a片| 粉嫩小泬久久久一区二区| 性爱免费视频成人| 亚洲另类色综合网站| 国产 日韩 另类 视频一区爱| 国产91丝袜 在线播放| 一道本久久棕合爱| av爱爱爱| 亚洲少妇激情一区二区三区| 又黄又爽在线观看视频| 超碰精品日韩欧美国产| 日欧毛片久久| 热久久91婷婷| 亚洲综合中文字幕有码| 久久久91| 亚州中文字幕超碰97| 日本Xx性爱| 操一对老熟妇爽上天视频| 欧美亚洲激情小说| 欧美人妻一区| 国产亚洲深夜激情| 91欧美色| 天天综合网1| 成人av动漫在线观看| 2017天天操| 日韩99神马视频播放| HEYZO高无码国产精品227| 精品人妻av区天天看片| 老女人老91妇女老热女| 九九成人| 亚洲限制级| 久久男女激情视频网站| 天天懆天天日| 欧美影院一区二区三区| 精品制服美女中文一区二区三区| 91久久精品国产| 欧亚性爱啪啪| 欧美成熟性爱精品| 91一区二区三区蜜桃| 蜜桃午夜视频一区二区 | 欧美日韩亚洲天堂| 国产精品另类一区大香蕉| 蜜臀亚洲中文| 天天爱天天韩国日本牛牛牛牛| 91在线超高颜值国产| 啊啊啊爽爽| 欧美女同在线| 成人精品水蜜桃久久久久久久| 91人妻视频在线| 伊人五月天| 国产精品久久久久久久AV大片| 伊色久人大在线| 国模91| 北京美女一区二区| 亚洲 欧美 另类 日韩 人妻一区| 91九九九馒头| 五月天伊人| 亚洲 欧美 手机在线观看| 国产精品爱欲| 亚洲一卡二卡在线免费| 国产传媒午夜理伦精品| 色激情综合网站| 国产三级片在线观看| 少妇激情AV| 91美女色视频亚洲| 黄色污污污污污污网站| 老熟女91| 欧美激情久久久久| 色网综合网| 麻豆伊人网| 大香蕉伊人一区在线观看| 国产精品日日摸夜夜添骚逼| 色综合99999| 国产精品乱人伊人网| 久草大| 国产精品激情久久久久久久| 国产精品人妻熟女aⅴ| 97无码视频在线播放| 一本色道久久综合精品婷婷| 久久精品中文字幕女同| 无码人妻系列少妇| 97久久久精品| 国产天天骚| 日本丝袜美腿人妻九九| 欧美亚洲se91| 精品无码人妻一区二区免费蜜桃| 天美传媒av一区二区| 久草草一二三四区久久| 久草久日| 日韩免费a级毛片无码a∨| 在线视频97| 自拍偷拍国产欧美日韩韩| 伊人丁香五月婷婷| 丁香六月激情综合| www四虎| 欧美se亚洲| 一区二区视频你懂的| 国产精品3| 91久| 熟女激情综合网| 操逼片国产| **一级毛片国产| 日韩啪啪啪啪啪| 亚洲熟妇乱女区二区三区| 天堂精品一区| 九九色影院| 国产女上位好爽在线| 国产视频一区二区三区久久亚洲天堂| 亚码人妻| 97欧美超碰| 377p欧洲日本亚洲大胆| 99热这里是精品| 91欧美偷拍| 熟女熟妇一区二区三区视频| 天天综合91| 中文字幕一区二区在线日韩精品| 开心五月天激情网| 午夜福利在线合集| 免费试看60秒| 精品性爱一二三区| 男人的天堂欧美| 97精品视频在线播放| 国产成人在线观看网址| 无码在线亚洲| 亚洲天堂另类小说男人| 校园春色 亚洲| 中文字幕人妻资源在线| 婷婷色色五月| 久久成人东京热人妻| 亚洲黄片免费在线播放| 99热这里只有精品9| 欧洲久久一二线| 国产精品探花视频| 歐美性天天| 欧美色图91| 超碰成人最新最好看| 人妻插插人妻人| 亚洲男人天堂手机版| 天天激情干| 免费看美国人人爽,人人操 | 新久久AV| 抽查国产福利主播| 91美女小视频| 99热精品免费| 亚洲自拍小说| 亚洲色图殴美色图激情乱伦| 九九九影院| 91被操| 超碰三级秋霞| 久一区久久蜜桃| 深田咏美亚洲精品福利社 | 91丨熟女丨丰满熟女| 亚洲人在线成线成人| 人人妻人人玩人人澡人人爽| 99热9| 蜜汁欧美| 五月丁香啪啪啪| 久热这里| 五月综合色| 风间由美日韩欧美久久| 91狼人| 97国产中文| 国产激情综合| 91殴美| 亚洲熟妇自偷自拍另欧美| 97久久超碰日韩精品| 亚洲另类电影| 亚洲91在线| 亚洲麻豆精品二区三区| 激情小说亚洲色图| 色女综合| 99久久婷婷丁香| 欧美激情亚洲情色| 激情深爱五月天| 本道综合精品| 日本免费不卡二区| 国产AV色黄看到爽| 本道在线| 超碰亚洲欧美日韩无| 国产色产精品在线观看| 91殴美大片| 日韩欧美aⅴ综合网站发布| 国产日韩手机视频在线| 亚洲视频一二区| 亚洲一级特黄大片在线播放91| 亚洲图片 激情小说| 精品国产乱码久久久久久口爆网站| 色香91| 久久,精品一二三| 欧美巨大性舒爽顶到了| 神马久久69| 六十路日本| 激情综合网激情综合| 屌妞视频久久久久久久久久久久| 亚欧无码在线| 999综合网| 麻豆国产成人精品| 先锋精品av色鲁| 91久久免费视频互動交流| 亚洲有码第一页| 色婷婷在线视频| 青草草免费网站av| 97国产|免费| 神马久久网| 在线不卡视频| 国产日逼视频| 久久啊啊| 国产AV人人夜夜澡人人爽麻豆| 天天综合色| www.久久制服糖| 国产丁香精品露脸视频| 日韩簧片免费看| 欧美色997| 一级A啪啪啪啪| 欧美性爱日韩高清| 91日产桃蜜| 9久久久久久| 骚女天天综合网| 精品国产乱码久久久久久久久久毛片| 打av高清| 夜夜国产一区| 91九九九逼| 大香蕉99热| 久久精品老司| 啊啊啊啊操死我了| 久久婷婷电影网| 国产精品老师| 婷婷色香伊人| ai欧美亚洲小说| 9+1视频网址| 欧在线一二区| 国产无马视频| 冬京热男人的天堂| 韩国嫰模上门援交视频| 国产精品国产精品国产| 天天上日日上日韩精品| 天天久久久久久| 欧美激情亚洲情色| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 久久老子无码午夜伦不卡| 欧美性爱视频免费一区一A | 免费观看一区| WWW.操逼.COM| 九九精品99| 婷婷色五月激情| 欧美综合色站| 超碰欧美COM| 亚洲精品久久久久毛片A片拉屎| 成人97人人超碰人人| 五月婷婷丁香中文字幕| 国产av白丝| 999久久芭蕾| 日本操逼视频免费| 97碰在线视频| 69久久久久久久久久久久久| 蜜臀久久99精品久久久久久酒店 | 久久久久久久久9| 日本久久女同性恋视频| 国内自拍 日韩激情 99| 97超碰逼| 乱伦熟女论坛| 天美传媒国产原创中文字幕亚洲欧美另类 | 青青草日本中文字幕| 九九热re99re6在线精品| 强奸乱伦中文字幕AV| 欧州激情视频在线一区二区| 一级性爱网| 丝袜六区| 性爱乱伦一区| 97在线观| 翔田千里AV无码秘 三区| 91熟女视频| 精品99999| 国产三级片在线观看| 夂久色| 久久9精品| 国产三区免费在线观看| 99re免费| 国产精品国产| 综合久久欧美| 四虎精品一区二区| 色淫网站优优视频| 亚洲欧洲日韩国产自在线| 久久国产对白激情浪潮 | 久久影视二区三区行押| 精品97精品97| 久久精品72| 大香蕉综合久久| 久久激情网| 另类欧美| 正在播放:深夜激情大战,自带黑丝袜全力输出骚穴 | 九九九精品美女| 99色在线| 亚洲国产欧美一区二区潘金莲| 久久久专区| 熟女人妻一区二区三区| 久久一二三四| 动漫av中文| 欧美性天天影视| 91社区拍啪人妻| 极品肉射| 久久久性少妇| 诱惑人妻欧美一区在线播放| 色牛牛AV| 国产精品自拍xxxx| 密臀视频三区免费网站| 日韩一级二级三级免费看完整版国语版| 国产91久久九九免费精品无码| 日韩情色一区二区| 在线电影亚洲色图| 九九国产| 欧洲一区二区三区免费| 亚洲人成网www| 九九香蕉网| 中日韩欧美精品无码AⅤ一区二区| 亚洲毛片基地专区| 97资源站国产精品| 狠狠色婷婷7777久| 亚洲色五月| 97超碰9| 九九热在线视频| 亚洲图片欧美偷拍| 中文字暮97| 精品国产乱码久久久久久久久1 | 久久国产视频性吧 | 91xingse| 91肉丝| 欧美综合网A| 丁香五月色| 精品成人av一区二区三区在线| 超清福利精品视频在线| 国产强奸乱伦第1页| 国产sv美女内射| 久久香蕉国产线看观看亚洲女人 | 亚洲91av| 极品五月天噜噜| 日本人体九九九九九九| 亚洲综合码| 天天摸夜夜操视频| 国产精品毛片| 久久久久久久精| 日本一级特级毛片视频| 密乳AV免费观看| 国产成人自拍视频在线| 精品女人999| 欧美大战久久久伊人| julia ann久久| 久久精品| 国产成人无码高清| 黑丝91视频| 伊人网一本| 日韩啊V| 久久久久久AⅤ无码免费肉站| 色五月综合| 好舒服视频| 曰韩中文人妻视频| 人妻大相焦在线| 理论久久婷婷网 8| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 久久AV无码AV| 男男H黄动漫啪啪无遮挡网站| AV中文在线| 综合久| 人妻精品4K4K4K4K4| 嗯啊不要啊在线 | 在线一道啪| 五月天丁香| 亚洲丝袜制服国产91_国语字幕免费观看完整版下载第5集_ | 天天日夜干| 欧美色九九九| 国产亚洲精品自在线亚洲情侣| 亚洲熟伦熟妇AV无码春色| 亚洲无套久久嗯嗯| 加勒比海成人视频网 | 亚洲人成色9999精品久久| 情色五月天就去干| 国产真实野战在线视频| 伊人久久亚洲色欲综合网站 | 欧美另类色| 久久人妻熟女一区二区| 97操操| 97欧美色| 激情综合五月婷婷| 999热这里只有精品| 看日韩美女二区三区免费操逼视频 | 天美传媒精品一区二区| 超碰人人妻| 欧美一区二区男人天堂| 人妻一区二区三区| 久久双插| 懂色av中文字幕一区二区三区天美| 成人亚欧免费视频| 亚洲欧美天| 精品一区二区三区蜜桃臀赵总 | 3P丝袜熟女 色综合| 婷婷视频在线免费观看| 国产麻豆福利av在线播放| 日日嗷| 久久精品操| 国产91 丝袜在线播放00-百度| 成人午夜高潮av猛片| 亚洲中文字幕久久人妻| 人妻 中文 日韩| 少妇无码av专区线| 艹精品| 精品九九国产无码| 婷婷丁香五月激情啪啪| 人人操av| 国产黄色 A 片免费看| 夜夜春夜夜操| 色噜噜综合在线| 中国熟女91| 亚洲天堂区| 日韩不卡av一二三| 九月丁香婷婷色| 婷婷色综合| 精品久久久不卡一区二区| 中文字幕一二三av| dy888午夜老子影视达达兔| 韩国一级婬片A片AAAAA| 97av在线观看| 日韩精品99999| 国产一区二区视频在线播放| 99re8超碰| 五月天精品| 五月丁香激情啪啪| 人妻人人做人人澡人人爽欧美一区| 国产精品96| 东北女人性交| 欧美淫乱视频| 91青青在线视频| 日日日色色色色色| 欧美大香蕉97| 夜夜騷av、一區二區| 久久女人视频| 免费农村成人少妇人妻Aa一区二区视频 | 啊啊啊啊在线播放| 午夜AV污污污| 久久久月天| 熟妇人妻精品一区二区| 久草综合网| 91丨人妻丨国产丨丝袜| 男人天堂网址| 老外又粗又长一晚做五次| 亚洲人体视频在线观看| 久久国产乱子伦精品免费女人| 超碰在线人妻中文字幕| 国产精品视频麻豆入口| 婷婷AV一区二区三区| 久久一区二区三区入口| 五月丁香狠狠爱| 在线视频一区二区传媒| 欧美熟女丝袜| 精品一区二区三区丰满熟女-亚洲欧美一区| 天天色欧美| 国产精品久久久久久久AV大片 | 福利在线黄片| 四虎影视 亚洲无码| 91香蕉国产尤物视频| 欧美成人色| 日韩国语字幕| 亚洲国产成人精品久久久国产成人一区二区三.| 天美av在线| 国产欧美精品日韩区二区麻豆天美| 国产精品suv一区| 在线不欧美| Av色五月| 6080YYY午夜理论片在线观看| 1234区中文字幕在线观看_青青草国产在线_日韩一区二区 | 亚洲乱伦图片视频| 成人AV素股で擦久久| 高潮的A片激情扒开一区| 亚洲第一二区另类图| 高清视频一区| 18禁中文字幕| 欧洲综合视频| 阿姨一区二区免费视频-高清正片西瓜视频下载app-T450AV | 一及黄久一点| 99精品在线观看| 91狼人| 免费家庭乱伦视频| 最新无码国产| 欧美日韩在线国产在线| 中文字幕人成乱码熟女香港| 久久一区,青青青青草视频在线播放| 精品色色| 91jk色拍| 国产丝袜啪啪| 啊啊啊啊嗯嗯在线久久久| 十八禁黄色| 思思热国产高清| 情色大香蕉| 亚洲资源吧| 97久久超碰日韩精品| 色综合天天| 伊蕉97蜜桃97狠狠综合干| 免费观看网黄| 亚洲性猛| 天天日天天操心| 欧美少妇人妻| 97超碰热线| 国产91福利小视频在线观看| 国产又黄又爽| 国产精品麻豆视频网站| 超碰久久精品| 少妇超碰在线| 久久男人精品| 99少妇| 少妇天堂网络| 欧美日韩操逼嗦吊| 五月天我淫我色av| 91痴汉| 69视频福利导航| 成人午夜无码视频| 日韩免费簧片| 一本色道人妻久久| 国产又大又粗又色生活片亚洲国产精品成人久久久综合免费 | 一区二区首页| 国产精品亚洲一区二区三区四区| 国产久久久久久| 久久精品国产97欧美精品亚洲 | 97人肏| 盗摄女人妻在线| 天天日天天操天天射河南省| 欧亚日本情色| 91成人国产综合久久精品蜜月| 久湿久久| 97超碰中文字幕| 青青操网| 美女大乳久久久久久久女人18| 啊啊啊啊啊啊好多水| 天天做日日爱夜夜爽| 极品AV网站在线观看| 日日夜夜精品视频| 久久99九九九九6666免费观看软件| 在线中文AV| 午夜后入| 99这里只有精品| 操一对老熟妇爽上天视频| 97在线亚洲| 在线电影亚洲色图| 91 亚洲情侣偷拍 久久| 欧亚洲精品有视频| 日本色色色视频| 加勒比99999| 丁香六月综合激情| 91精品无码人妻系列| 亚洲天在线| 97色色国产视频| 成人性爱全视频观看| 亚洲天堂日本| 日欧操屄| 人妻人久久精品中文字幕| 97中文天堂| 欧美三级一级| 亚洲色图欧美色图制服诱惑| 男女香蕉一区二区| 99热这里都是精品| 国产在线视频午夜精华在| 亚洲欧美高清无码| 久久亚洲AV无码专区国产精品| 福利在线观看一区二区| 97色色视频| 超碰中文字幕人妻草一区| 超碰精品人妻狠狠干| 欧美中文综合| 亚洲最大的综合性av| 91蜜桃婷婷狠狠久久综合9色| 人人爱夜夜爱| 91n处女在线观看| 无码久久国产| 久/久精品99看9| 欧美夜色| 激情综合网激情综合| 图片区小说区| 中文字幕女同在线| 精品无码秘 人妻一区二区| 你懂得91| 日本高清一本二本免费不卡| 黄色电影在线播放综合网站| 欧美激情综合色综合啪啪五月| 黄呦呦在线| 98人妻精品一区二区色欲| 99久久久| 精品视频一区二区| 亚洲图片偷拍视频区| 久久99草| 国产午夜激片Av毛片不卡| 九九九九九用不成了| 一级岛国大片| 国产精品欧美激在线| 国产黄色小视频网站| 亚洲色9| 亚欧毛片基地国产毛片基地| 国内黄色精品| 两女互慰AV高潮喷水在线观看| 内射白嫩美女| 亚洲日本激情| 国产美女在线精品免费看| 久操婷婷| 欧美特大黄一级片片免费| 在线无码网站| 日韩美女操b| 嫩草影院在线观看精品| 欧美专区日本专区| 婷婷五月天福利| 精品人妻一区二区免费蜜桃| 亚洲砖码砖专无区2023| 婷婷色色五月天福利| 伊人骚琪琪亚洲天堂网站| 久草精品一区| 高清不卡视频| 91粉芽高清在线一区二区| 极品白嫩美女白浆成人福利在线看| 尤物av网站免费在线播放| 99综合视频一体| 中文操逼字幕| 一级乱伦网站| 717影院理论午夜伦八戒| 综合网97| 久久25| 国产粉嫩出水在线播放| 精品久9| 欧美一区二区三区另类精品| 蜜臀AV一区二区三区激情综合| 国产午夜福利专区综合| 亚洲黄色网址视频| 天天享受天天看| 人人操,操人人| 999精品久久久久久久| 亚热日本熟女| 99爱久久视频频| 久操婷婷| 狠狠狠狠狠| 看一级特黄a大一片| 操操操五月天婷婷丁香影院| 欧美色图小说综合| 99国内熟女露脸视频| 日本大香蕉| 天天日日本| 啊啊啊好湿久久| 曰韩欧美国产传媒麻豆第一区| 性爱av网站| 小情侣高清国产在线视频| 国产精品成人无码a v毛片| 超碰av人人人| 久久久精品国产亚洲伊人| 91久久久久久久| 欧美亚洲日韩人妻在线观看| 91粉嫩萝控精品福利网站_精品影音先锋国| 欧美1区二区三区公司| 日本αv| 乱伦熟女专区| 国产av又色又爽又黄| 自拍偷拍 日韩无码| 亚洲欧美成人在线| 夜夜操91744565| 10000部十八禁看电影| 久久啊啊啊视频| 日韩成人人妻网站| 综合久久9| 激情网色| 五月丁香综合| 91总综合网| 欧美啪啪啪91| 免费人成毛片乱码| 成人免费福利网站国产| 亚洲人妻一区二区三区| 亚洲精品欧洲精品| 久久精品女同亚洲女同13| 亚洲一区二区三区春色| 最新中文字幕精品在线| 亚洲有薄码区日本系列中文字幕| 啊嗯好大视频在线观看| 日韩综合第八区国产精品| 又大又大又大又粗爽高潮观看| 日韩欧美综合激情| 中文字幕一区 二 区 三 四 五 区日 日 骚| 国产高清不卡视频| 啪啪啪亚欧美视频| 欧美夜色| 国产精品一区二区三区四区五区| 亚州精人品大香蕉| 日本色色色视频| 五月天我淫我色av| 日本道日本道中文字幕日本道最新日本道在线观看 | 日本性爱视频一级| 依人大香蕉| 久久99干一本高清| 最新三级网址| 亚洲一二三四区在线免费看视频| www.99色| 成人熟女视频一区二区三区| 青草成人免费视频一COm| 亚洲经典啪啪| 亚洲资源一区| 麻豆天美国美国产| 在线视频资源| 激情六月婷婷| 俺去啦俺来也久久综合| 啊啊啊啊啊在线视频| 不卡六六在线91| 国产美女高潮叫床视频| 99亚洲人人| 亚洲色图 欧美| 亚洲国产剧情少妇激情| 亚洲无码电影久久久| 色五月婷婷在线| 久久久久久久久久久久97| 91综合在线| 97超碰人妻| 亚洲日韩AV视色| www亚洲欧美| 五月丁香成人网| daxiangjiao你懂的| 亚洲熟女人妻中文字幕一区二区| 一区二区三区美女超清| 99re公开精品免费视频| 99热aaa| 男人的天堂VA| 亚洲人妻av| A一级色女| 深田咏美亚洲精品福利社| 欧美影音在线| 精品无吗m| 婷婷深爱五月| 五十路人妻在线| 久久久久久网址| 天美AV片| 久久人妻| 天天日B狠狠操| 九九九九九九九九九国产精品| 九九aV| 偷偷人人精品女女久久| 中日韩熟女| 很狠操| 啊啊啊好湿国产一二| 国产高清成人传媒影视| 91日韩国产欧美亚洲另类精盘州至城都| 少妇内射www在线观看视频 | 怡红院成人视频| 日韩免费av片高清无码| 九九久久首页| 久久在线观看免费视频| 麻豆av一区二区三区| 狠狠婷婷亚洲中文综合久久| 成人精品电影| 蜜乳成人AV| 欧美青青视频| 亚洲综合中文字幕有码| 少妇人妻在线| 99在线观看| 91视频综合网| 久久一二三四不卡| 中文字幕亚洲热播人妻| 死我十八禁| 亚洲激情久久| 性综合网| 草久久久| 亚州AV无码国产精品| 抽插一区二区视频| 91麻豆天美国产欧美| 国内偷拍精品一区二区| 好看的久久不射无码影视影院| 日本精品无码三级网站| 久久精品无码熟妇一区二区三区视频导航 | 97se亚洲| 精品久久在线区一区| 91人妻精华帖| 亚洲色图8| 日本不卡三级网在线播放| 超碰无码加勒比| 后入日本1234| 67914亚洲精品| 伊人精品久久网站| 久九九九九九九九热| 久久久久久久少妇| 一区二区视频在线播放| 成人国产二区三区在线,男女精品。| 欧美人妻二区三区| 亚洲精品中文字幕一区在线视频 | 日韩精品人妻一| 快灬快灬 一下爽蜜桃在线观看| 欧美内射少妇| 大香蕉综合| AV一起草在线| 久久婷婷一区| 330Dv国产女人终合视频极品人与兽 | 亚洲国产欧美日韩人妻日中文| 人人摸.人人色| 91亚洲影视| 无毛精品| 久久这里精品国产99丫e6| 久久‘黄片视频| 国产91av在线播放| 超碰97日韩| 啊啊啊啊啊啊啊在线| 色999人与兽| 日韩AC| 最新亚洲人成网站在线影院| 国产97色在线 | 亚洲| 国产熟妇一区二区| 色精品极品| AV综合中文字幕干| 日本激情免费大片| av网站国产主播在线| 久久三区四区| 欧美最大综合网| 国产乱弄免费在线视频。| 99热这里是精品| 日韩精品永久在线观看| 久热在线精品免费观看| 久久久久亚洲| 久久精品无码一区二区三区| 久湿久久| 97精品国产手机| 91搞逼视频| 国产久久久久久久久一区二区| 国产肏逼网站| 97网色| 亚欧美色图| 色香欲天天天天综合色| 日韩人妻无码精品系列| 嗯啊啊啊轻点视频 | 无码 有码 国产18p| 亚洲成人日韩小说| 国产精品人人爽人人做可爱福利| 人妻少妇久久中文字幕一区二区 麻豆| 国产精品禁久久久精品| 热热色综合网| 97国产精品久久久久| 久操网在线| 神马久久啊啊| 日韩av色图| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | av中文在线| 丁香久久| 一区二区偷拍拍视频| 国产毛片精品一区二区色欲黄A片| 日韩去日本高清在| 99日精品欧美国产| 噜噜吧,噜噜色,噜噜| 日韩午夜啪啪视频| 乱色视频中文字幕| 97色在线| 天天看综合网| 超碰国产情侣自拍网| 综合干干干av久久久综合网| 美女淫穴| 素颜老阿姨乱情色| 久久久久久久久久久久久女过产乱-少妇高潮一区二区三区喷水-成人AV | 欧美精品精品一区二区| 性爱网站一区二区| 亚洲自拍天堂| 91快色色色色色|