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