原理
@Transactional 是聲明式事務(wù)管理 編程中使用的注解馆截,通過Spring AOP在注解修飾方法的前后織入事務(wù)管理的實(shí)現(xiàn)語句,所以開發(fā)者只需要通過一個(gè)注解就能代替一系列繁瑣的事務(wù)開始、事務(wù)關(guān)閉等重復(fù)性的編碼任務(wù)框产。
添加位置
接口實(shí)現(xiàn)類或接口實(shí)現(xiàn)方法上,而不是接口類中错洁。
訪問權(quán)限:public 的方法才起作用秉宿。@Transactional 注解應(yīng)該只被應(yīng)用到 public 方法上,這是由 Spring AOP 的本質(zhì)決定的墓臭。
系統(tǒng)設(shè)計(jì):將標(biāo)簽放置在需要進(jìn)行事務(wù)管理的方法上蘸鲸,而不是放在所有接口實(shí)現(xiàn)類上:只讀的接口就不需要事務(wù)管理,由于配置了@Transactional就需要AOP攔截及事務(wù)的處理窿锉,可能影響系統(tǒng)性能酌摇。
錯(cuò)誤案例
1.同一個(gè)類中調(diào)用
public?class?A?{
????
????public?void?methodA()?{
????????methodB();
????????
????????// 其他操作
????}
????@Transactional
????public?void?methodB()?{
????????// 寫數(shù)據(jù)庫操作
????}
????}
上面案例是錯(cuò)誤的基于Spring Aop的攔截機(jī)制,將會(huì)忽略事務(wù)嗡载。解決方式如下:
@Service
@AllArgsConstructor
public class A {
????
????private?B?b;
????
????public?void?methodA() {
????????b.methodB();
????????// 其他操作
????}
}
@Service
public?class?B?{
????@Transactional
????public void methodB() {
????????// 寫數(shù)據(jù)庫操作
????}
????}
注意:這里的B類沒有用@Autowrire窑多,構(gòu)造函數(shù)用Lombok的@AllArgsConstructor生成 自動(dòng)注入了。
2. @Transactional修飾方法不是public
public?class?TransactionalMistake?{
????
????@Transactional
????private?void?method()?{
????????// 寫數(shù)據(jù)庫操作
????}
????}
這也是基于Spring AOP實(shí)現(xiàn)的注解所要滿足的要求洼滚。這個(gè)最簡單, 直接把方法訪問類型改成public即可埂息。
3. 不同的數(shù)據(jù)源
public?class?TransactionalMistake?{
????@Transactional
????public?void?createOrder(Order order)?{
????????orderRepo1.save(order);
????????orderRepo2.save(order);
????}
}
上面這個(gè)例子里的orderRepo1和orderRepo2是連接的兩個(gè)不同數(shù)據(jù)源。默認(rèn)情況下遥巴,這種跨數(shù)據(jù)源的事務(wù)是不會(huì)成功的千康。如果要在多個(gè)數(shù)據(jù)源之間實(shí)現(xiàn)事務(wù),那么可以引入JTA铲掐。
4. 回滾異常配置不正確
默認(rèn)情況下拾弃,僅對RuntimeException和Error進(jìn)行回滾。如果不是的它們及它們的子孫異常的話摆霉,就不會(huì)回滾豪椿。如果不是RuntimeException,但也希望觸發(fā)回滾携栋,那么可以使用rollbackFor屬性來指定要回滾的異常搭盾。
public?class?TransactionalMistake?{
????@Transactional(rollbackFor = XXXException.class)
????public?void?method()?throws?XXXException {
????}
}
5. 數(shù)據(jù)庫引擎不支持事務(wù)
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
這里的spring.jpa.database-platform配置主要用來設(shè)置hibernate使用的方言。這里特地采用了MySQL5InnoDBDialect婉支,主要為了保障在使用Spring Data JPA時(shí)候鸯隅,Hibernate自動(dòng)創(chuàng)建表的時(shí)候使用InnoDB存儲(chǔ)引擎,不然就會(huì)以默認(rèn)存儲(chǔ)引擎MyISAM來建表向挖,而MyISAM存儲(chǔ)引擎是沒有事務(wù)的滋迈。
點(diǎn)擊下方卡片/微信搜索霎奢,關(guān)注公眾號(hào)“天宇文創(chuàng)意樂派”(ID:gh_cc865e4c536b)
聽說點(diǎn)贊和關(guān)注本號(hào)的都找到漂亮的小姐姐了喲且年后必入百萬呀!饼灿!
本文使用 文章同步助手 同步