摘要:假如你寫(xiě)了類(lèi)似這樣的和偽代碼問(wèn)題來(lái)了,和分別用了兩個(gè)分開(kāi)的事務(wù),如果你用了或,并且是的,這就沒(méi)法運(yùn)行。你需要讓兩次調(diào)用運(yùn)行在同一個(gè)事務(wù)里。
當(dāng)你采用Spring之類(lèi)的框架,用了聲明式事務(wù),難道每一段需要事務(wù)的代碼都必須寫(xiě)成一個(gè)bean method,再標(biāo)上@Transactional?
未免太麻煩了,不信你瞧。假如你寫(xiě)了類(lèi)似這樣的Controller和Service (偽代碼):
class UserController { @Autowired UserService us; String updateUser(long userId) { User user = us.authorize(userId); Event e = us.update(user); publishToMQ(e); return "user-page"; } } @Transactional class UserService { User authorize(long userId) {...} void update(User user) {...} }
問(wèn)題來(lái)了,authorize和update分別用了兩個(gè)分開(kāi)的事務(wù),如果你用了Hibernate或JPA,并且user是lazy-loading的,這就沒(méi)法運(yùn)行。你需要讓兩次調(diào)用運(yùn)行在同一個(gè)事務(wù)里。通常的辦法是把UserController.updateUser也標(biāo)成@Transactional??墒沁@么一來(lái),下一句publishToMQ(e);雖然不需要事務(wù),卻也被包在事務(wù)里了。
我們可以做得更好!用Java 8做一個(gè)Transactor,任何代碼塊可隨時(shí)包在事務(wù)中!
然后controller可以重寫(xiě)為:
String updateUser(long userId) { Event e = Transactor.get().apply(() -> { User user = us.authorize(userId); return us.update(user); }); publishToMQ(e); return "user-page"; }
Transactor的實(shí)現(xiàn):
@Component @Transactional public class Transactor { public static Transactor get() { return instance; } publicR apply(Supplier f) { return f.get(); // 有返回值的代碼塊 } public void run(Runnable f) { f.run(); // 無(wú)返回值的代碼塊 } @Autowired private ApplicationContext applicationContext; @PostConstruct void setup() { instance = applicationContext.getBean(Transactor.class); //不能寫(xiě)instance=this } private static Transactor instance; }
代碼中透出四個(gè)字:靈活,簡(jiǎn)潔!
2015/7/5 Update: 可惜的是,有時(shí)會(huì)拋出org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread (雖然stacktrace中是有代理類(lèi)的)
目前實(shí)測(cè)改用Spring的TransactionTemplate是可以的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/64318.html
摘要:網(wǎng)上介紹和集合新特性的代碼太千篇一律了,我來(lái)提供些不一樣的?;蛘邔?shí)現(xiàn)如下它的實(shí)現(xiàn)沒(méi)有使用,因?yàn)槭且环N強(qiáng)大到能延遲處理和并行處理的,我們簡(jiǎn)單的集合操作不需要這么高級(jí)的能力。目前只寫(xiě)了三個(gè)方法,如果有需求,還可以擴(kuò)充更多的方法。 網(wǎng)上介紹Java 8 lambda和集合新特性的代碼太千篇一律了,我來(lái)提供些不一樣的。雖然很簡(jiǎn)單,但也是工業(yè)級(jí)代碼,不是網(wǎng)上抄來(lái)抄去的教學(xué)代碼。權(quán)當(dāng)給大家提供一個(gè)...
摘要:通常,這種模式是通過(guò)定義一個(gè)代表處理對(duì)象的抽象類(lèi)來(lái)實(shí)現(xiàn)的,在抽象類(lèi)中會(huì)定義一個(gè)字段來(lái)記錄后續(xù)對(duì)象。工廠模式使用表達(dá)式第章中,我們已經(jīng)知道可以像引用方法一樣引用構(gòu)造函數(shù)。 一、為改善可讀性和靈活性重構(gòu)代碼 1.改善代碼的可讀性 Java 8的新特性也可以幫助提升代碼的可讀性: 使用Java 8,你可以減少冗長(zhǎng)的代碼,讓代碼更易于理解 通過(guò)方法引用和Stream API,你的代碼會(huì)變得更...
摘要:本章中的大部分內(nèi)容適用于構(gòu)造函數(shù)和方法。第項(xiàng)其他方法優(yōu)先于序列化第項(xiàng)謹(jǐn)慎地實(shí)現(xiàn)接口第項(xiàng)考慮使用自定義的序列化形式第項(xiàng)保護(hù)性地編寫(xiě)方法第項(xiàng)對(duì)于實(shí)例控制,枚舉類(lèi)型優(yōu)先于第項(xiàng)考慮用序列化代理代替序列化實(shí)例附錄與第版中項(xiàng)目的對(duì)應(yīng)關(guān)系參考文獻(xiàn) effective-java-third-edition 介紹 Effective Java 第三版全文翻譯,純屬個(gè)人業(yè)余翻譯,不合理的地方,望指正,感激...
摘要:上下文比如接受它傳遞的方法的參數(shù),或接受它的值的局部變量中表達(dá)式需要的類(lèi)型稱(chēng)為目標(biāo)類(lèi)型。但局部變量必須顯式聲明為,或事實(shí)上是。換句話(huà)說(shuō),表達(dá)式只能捕獲指派給它們的局部變量一次。注捕獲實(shí)例變量可以被看作捕獲最終局部變量。 簡(jiǎn)介 概念 Lambda 表達(dá)式可以理解為簡(jiǎn)潔地表示可傳遞的匿名函數(shù)的一種方式:它沒(méi)有名稱(chēng),但它有參數(shù)列表、函數(shù)主體、返回類(lèi)型,可能還有一個(gè)可以?huà)伋龅漠惓A斜怼? 匿名...
閱讀 1911·2021-10-11 10:57
閱讀 2572·2021-10-08 10:14
閱讀 3478·2019-08-29 17:26
閱讀 3504·2019-08-28 17:54
閱讀 3103·2019-08-26 13:38
閱讀 3025·2019-08-26 12:19
閱讀 3686·2019-08-23 18:05
閱讀 1379·2019-08-23 17:04