最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于spring中事務(wù)的傳播機制

 更新時間:2023年05月15日 08:50:47   作者:morris131  
這篇文章主要介紹了關(guān)于spring中事務(wù)的傳播機制,所謂事務(wù)傳播機制,也就是在事務(wù)在多個方法的調(diào)用中是如何傳遞的,是重新創(chuàng)建事務(wù)還是使用父方法的事務(wù),需要的朋友可以參考下

Spring中的事務(wù)

Spring的事務(wù)其實就是數(shù)據(jù)庫的事務(wù)操作,符合ACID標準,也具有標準的事務(wù)隔離級別。

Spring中的事務(wù)只是對JDBC事務(wù)進行一些封裝與擴展,其底層最終還是會使用到JDBC的這套API。但是Spring事務(wù)有自己的特點,也就是事務(wù)傳播機制。

所謂事務(wù)傳播機制,也就是在事務(wù)在多個方法的調(diào)用中是如何傳遞的,是重新創(chuàng)建事務(wù)還是使用父方法的事務(wù)?父方法的回滾對子方法的事務(wù)是否有影響?這些都是可以通過事務(wù)傳播機制來決定的。

準備工作

實體類

Area

package com.morris.spring.entity;import lombok.Data;import java.io.Serializable;@Datapublic class Area implements Serializable {private Integer id;private String areaName;private Integer areaCode;}

Good

package com.morris.spring.entity;import lombok.Data;import java.io.Serializable;import java.math.BigDecimal;@Datapublic class Good implements Serializable {private Integer id;private String goodName;private BigDecimal price;}

DAO層

AreaDao

package com.morris.spring.dao;import com.morris.spring.entity.Area;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;public class AreaDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public boolean insert(Area area) {String sql = "insert into t_area(area_name, area_code) values(?,?)";return jdbcTemplate.update(sql, area.getAreaName(), area.getAreaCode()) > 0;}}

GoodDao

package com.morris.spring.dao;import com.morris.spring.entity.Good;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;public class GoodDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public boolean insert(Good good) {String sql = "insert into t_good(good_name, price) values(?,?)";return jdbcTemplate.update(sql, good.getGoodName(), good.getPrice()) > 0;}}

Service層

AreaServiceImpl

package com.morris.spring.service;import com.morris.spring.dao.AreaDao;import com.morris.spring.entity.Area;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;public class AreaServiceImpl implements AreaService {@Autowiredprivate AreaDao areaDao;@Transactional(propagation = Propagation.REQUIRED)@Overridepublic boolean addArea(int i) {int y = 1000000 / i;Area area = new Area();area.setAreaCode(y);area.setAreaName("shenzhen");return areaDao.insert(area);}}

GoodServiceImpl

package com.morris.spring.service;import com.morris.spring.dao.GoodDao;import com.morris.spring.entity.Good;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;public class GoodServiceImpl implements GoodService {@Autowiredprivate GoodDao goodDao;@Transactional(propagation = Propagation.REQUIRED)@Overridepublic boolean addGood() {Good good = new Good();good.setGoodName("iphone");good.setPrice(BigDecimal.valueOf(99999));return goodDao.insert(good);}}

TransactionService

package com.morris.spring.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;@Componentpublic class TransactionService {@Autowiredprivate GoodService goodService;@Autowiredprivate AreaService areaService;@Transactional(propagation = Propagation.REQUIRED)public void addGoodAndArea() {System.out.println("------addGoodAndArea-------");areaService.addArea(10);goodService.addGood();}}

測試類

TransactionPropagationDemo

package com.morris.spring.demo.jdbc;import com.morris.spring.config.JdbcConfig;import com.morris.spring.dao.AreaDao;import com.morris.spring.dao.GoodDao;import com.morris.spring.service.AreaServiceImpl;import com.morris.spring.service.GoodServiceImpl;import com.morris.spring.service.TransactionService;import org.junit.jupiter.api.Test;import org.springframework.context.annotation.AnnotationConfigApplicationContext;/** * 事務(wù)的傳播機制 */public class TransactionPropagationDemo {@Testpublic void test() {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();applicationContext.register(GoodDao.class);applicationContext.register(AreaDao.class);applicationContext.register(GoodServiceImpl.class);applicationContext.register(AreaServiceImpl.class);applicationContext.register(JdbcConfig.class);applicationContext.register(TransactionService.class);applicationContext.refresh();TransactionService transactionService = applicationContext.getBean(TransactionService.class);transactionService.addGoodAndArea();}}

傳播機制

具體選項可以參考枚舉類org.springframework.transaction.annotation.Propagation。

選項說明
REQUIRED默認選項。如果當前沒有事務(wù),就新建一個事務(wù),如果已經(jīng)存在一個事務(wù)中,加入到這個事務(wù)中。
SUPPORTS支持當前事務(wù),如果當前沒有事務(wù),就以非事務(wù)方式執(zhí)行。
MANDATORY使用當前的事務(wù),如果當前沒有事務(wù),就拋出異常。
REQUIRES_NEW新建事務(wù),如果當前存在事務(wù),把當前事務(wù)掛起。
NOT_SUPPORTED以非事務(wù)方式執(zhí)行操作,如果當前存在事務(wù),就把當前事務(wù)掛起。
NEVER以非事務(wù)方式執(zhí)行,如果當前存在事務(wù),則拋出異常。
NESTED如果當前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當前沒有事務(wù),則執(zhí)行與REQUIRED類似的操作。

REQUIRED

默認選項。如果當前沒有事務(wù),就新建一個事務(wù),如果已經(jīng)存在一個事務(wù)中,加入到這個事務(wù)中。

配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:REQUIRED
  • GoodServiceImpl:REQUIRED

運行上面的Demo,運行結(jié)果如下:

// 創(chuàng)建第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] to manual commit
------addGoodAndArea-------																				   
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 提交第一個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] after transaction

總結(jié):

  • 當外層沒有事務(wù)的時候,TransactionService.addGoodAndArea()方法執(zhí)行發(fā)現(xiàn)沒有事務(wù)可用,自己新建事務(wù)。
  • goodService.addGood()和areaService.addArea()執(zhí)行時發(fā)現(xiàn)已有事務(wù),就使用當前事務(wù)執(zhí)行。

REQUIRES_NEW

新建事務(wù),如果當前存在事務(wù),把當前事務(wù)掛起。

配置如下:

  • TransactionService:REQUIRED
  • GoodServiceImpl:REQUIRES
  • AreaServiceImpl:REQUIRES_NEW

運行結(jié)果如下:

// 創(chuàng)建第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] to manual commit
------addGoodAndArea-------																			   
// 掛起第一個事務(wù)并創(chuàng)建第二個事務(wù)
DEBUG DataSourceTransactionManager:446 - Suspending current transaction, creating new transaction with name [com.morris.spring.service.AreaServiceImpl.addArea]
// 創(chuàng)建第二個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@116fc68] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@116fc68] to manual commit
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 提交第二個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@116fc68]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@116fc68] after transaction
// 恢復(fù)第一個事務(wù)
DEBUG DataSourceTransactionManager:1043 - Resuming suspended transaction after completion of inner transaction
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] after transaction

總結(jié):areaServiceImpl.addArea()執(zhí)行時發(fā)現(xiàn)已有事務(wù),就把當前事務(wù)掛起,執(zhí)行完后再恢復(fù)。

SUPPORTS

支持當前事務(wù),如果當前沒有事務(wù),就以非事務(wù)方式執(zhí)行。

配置如下:

  • TransactionService:SUPPORTS
  • AreaServiceImpl:REQUIRED
  • GoodServiceImpl:SUPPORTS

運行結(jié)果如下:

// TransactionService.addGoodAndArea以非事務(wù)方式運行
------addGoodAndArea-------
// 開啟第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.AreaServiceImpl.addArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@1691f3d] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1691f3d] to manual commit
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 提交第一個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@1691f3d]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1691f3d] after transaction
DEBUG DataSourceTransactionManager:1043 - Resuming suspended transaction after completion of inner transaction
// AreaServiceImpl.addArea以非事務(wù)方式運行
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]

總結(jié):當前沒有事務(wù),TransactionService.addGoodAndArea()和AreaServiceImpl.addArea()以非事務(wù)方式運行。

修改配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:SUPPORTS
  • GoodServiceImpl:SUPPORTS

運行結(jié)果如下:

// 開啟第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@11158fb] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11158fb] to manual commit
------addGoodAndArea-------																		  
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
// 提交第一個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@11158fb]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11158fb] after transaction

總結(jié):當前有事務(wù),GoodServiceImpl.addGood()和AreaServiceImpl.addArea()以事務(wù)方式運行。

MANDATORY

使用當前的事務(wù),如果當前沒有事務(wù),就拋出異常。

配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:REQUIRED
  • GoodServiceImpl:MANDATORY

運行結(jié)果如下:

// 創(chuàng)建第一個事務(wù)
EBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@11c4a3f] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11c4a3f] to manual commit
------addGoodAndArea-------																  
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 在第一個事務(wù)中執(zhí)行
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
// 提交第一個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@11c4a3f]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11c4a3f] after transaction

總結(jié):當前有事務(wù),GoodServiceImpl.addGood()以事務(wù)方式運行。

修改配置如下:

  • TransactionService:SUPPORTS
  • AreaServiceImpl:MANDATORY
  • GoodServiceImpl:SUPPORTS

運行結(jié)果如下:

------addGoodAndArea-------
DEBUG DataSourceTransactionManager:888 - Should roll back transaction but cannot - no transaction available
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:374)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:205)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:219)
	at com.sun.proxy.$Proxy23.addArea(Unknown Source)
	at com.morris.spring.service.TransactionService.addGoodAndArea(TransactionService.java:20)

總結(jié):當前沒有有事務(wù),AreaServiceImpl.addArea()會拋出異常。

NOT_SUPPORTED

以非事務(wù)方式執(zhí)行操作,如果當前存在事務(wù),就把當前事務(wù)掛起。

配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:NOT_SUPPORTED
  • GoodServiceImpl:NOT_SUPPORTED

運行結(jié)果如下:

// 開啟第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] to manual commit
------addGoodAndArea-------
// 掛起第一個事務(wù)
DEBUG DataSourceTransactionManager:436 - Suspending current transaction
// 以非事務(wù)方式運行
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
DEBUG DataSourceUtils:115 - Fetching JDBC Connection from DataSource
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
// 恢復(fù)第一個事務(wù)
DEBUG DataSourceTransactionManager:1043 - Resuming suspended transaction after completion of inner transaction
// 掛起第一個事務(wù)
DEBUG DataSourceTransactionManager:436 - Suspending current transaction
// 以非事務(wù)方式運行
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
DEBUG DataSourceUtils:115 - Fetching JDBC Connection from DataSource
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
// 恢復(fù)第一個事務(wù)
DEBUG DataSourceTransactionManager:1043 - Resuming suspended transaction after completion of inner transaction
// 提交第一個事務(wù)
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] after transaction

總結(jié):執(zhí)行GoodServiceImpl.addGood()和AreaServiceImpl.addArea()時當前存在事務(wù),就把當前事務(wù)掛起。

NEVER

以非事務(wù)方式執(zhí)行,如果當前存在事務(wù),則拋出異常。

配置如下:

  • TransactionService:NEVER
  • AreaServiceImpl:NEVER
  • GoodServiceImpl:NEVER

運行結(jié)果如下:

// 沒有事務(wù)都以非事務(wù)方式運行
------addGoodAndArea-------
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
DEBUG DataSourceUtils:115 - Fetching JDBC Connection from DataSource
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]

總結(jié):當前沒有事務(wù)都以非事務(wù)方式執(zhí)行。

修改配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:NEVER
  • GoodServiceImpl:NEVER

運行結(jié)果如下:

// 開啟第一個事務(wù)
DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] to manual commit
------addGoodAndArea-------
DEBUG DataSourceTransactionManager:864 - Initiating transaction rollback
DEBUG DataSourceTransactionManager:345 - Rolling back JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] after transaction
org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:430)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:362)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:374)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:205)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:219)
	at com.sun.proxy.$Proxy23.addArea(Unknown Source)
	at com.morris.spring.service.TransactionService.addGoodAndArea(TransactionService.java:20)

總結(jié):AreaServiceImpl.addArea()執(zhí)行時存在事務(wù)就會拋出異常。

NESTED

如果當前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當前沒有事務(wù),則執(zhí)行與REQUIRED類似的操作。

配置如下:

  • TransactionService:REQUIRED
  • GoodServiceImpl:NESTED
  • AreaServiceImpl:NESTED

運行結(jié)果如下:

// 創(chuàng)建第一個事務(wù)
EBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
// 創(chuàng)建第一個連接
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] to manual commit
------addGoodAndArea-------
// 創(chuàng)建回滾點
DEBUG DataSourceTransactionManager:466 - Creating nested transaction with name [com.morris.spring.service.AreaServiceImpl.addArea]
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_area(area_name, area_code) values(?,?)]
// 釋放回滾點
DEBUG DataSourceTransactionManager:754 - Releasing transaction savepoint
// 創(chuàng)建回滾點
DEBUG DataSourceTransactionManager:466 - Creating nested transaction with name [com.morris.spring.service.GoodServiceImpl.addGood]
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
// 釋放回滾點
DEBUG DataSourceTransactionManager:754 - Releasing transaction savepoint
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] after transaction

如果不拋出異常,使用REQUIRED與NESTED都差不多,區(qū)別在于發(fā)生異常,下面演示REQUIRED與NESTED發(fā)生異常時的區(qū)別:

配置如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:REQUIRED
  • GoodServiceImpl:REQUIRED

TransactionService.addGoodAndArea修改如下:

@Transactional(propagation = Propagation.REQUIRED)
public void addGoodAndArea() {
	System.out.println("------addGoodAndArea-------");
	try {
		areaService.addArea(0);
	} catch (Exception e) {
		e.printStackTrace();
	}
	goodService.addGood();
}

運行結(jié)果如下:

DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] to manual commit
------addGoodAndArea-------
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG DataSourceTransactionManager:877 - Participating transaction failed - marking existing transaction as rollback-only
DEBUG DataSourceTransactionManager:360 - Setting JDBC transaction [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] rollback-only
java.lang.ArithmeticException: / by zero
	at com.morris.spring.service.AreaServiceImpl.addArea(AreaServiceImpl.java:18)
... ...
DEBUG DataSourceTransactionManager:487 - Participating in existing transaction
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
DEBUG DataSourceTransactionManager:723 - Global transaction is marked as rollback-only but transactional code requested commit
DEBUG DataSourceTransactionManager:877 - Participating transaction failed - marking existing transaction as rollback-only
DEBUG DataSourceTransactionManager:360 - Setting JDBC transaction [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] rollback-only
DEBUG DataSourceTransactionManager:723 - Global transaction is marked as rollback-only but transactional code requested commit
DEBUG DataSourceTransactionManager:864 - Initiating transaction rollback
DEBUG DataSourceTransactionManager:345 - Rolling back JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f9aa66] after transaction
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:905)
... ...

從運行結(jié)果可以發(fā)現(xiàn)事務(wù)全部都回滾了。

將上面的配置修改如下:

  • TransactionService:REQUIRED
  • AreaServiceImpl:NESTED
  • GoodServiceImpl:NESTED

運行結(jié)果如下:

DEBUG DataSourceTransactionManager:381 - Creating new transaction with name [com.morris.spring.service.TransactionService.addGoodAndArea]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG DriverManagerDataSource:144 - Creating new JDBC DriverManager Connection to [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=UTF-8&useFastDateParsing=false&zeroDateTimeBehavior=convertToNull]
DEBUG DataSourceTransactionManager:265 - Acquired Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] for JDBC transaction
DEBUG DataSourceTransactionManager:283 - Switching JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] to manual commit
------addGoodAndArea-------
DEBUG DataSourceTransactionManager:466 - Creating nested transaction with name [com.morris.spring.service.AreaServiceImpl.addArea]
DEBUG DataSourceTransactionManager:857 - Rolling back transaction to savepoint
java.lang.ArithmeticException: / by zero
	at com.morris.spring.service.AreaServiceImpl.addArea(AreaServiceImpl.java:18)
... ...
DEBUG DataSourceTransactionManager:466 - Creating nested transaction with name [com.morris.spring.service.GoodServiceImpl.addGood]
DEBUG JdbcTemplate:860 - Executing prepared SQL update
DEBUG JdbcTemplate:609 - Executing prepared SQL statement [insert into t_good(good_name, price) values(?,?)]
DEBUG DataSourceTransactionManager:754 - Releasing transaction savepoint
DEBUG DataSourceTransactionManager:763 - Initiating transaction commit
DEBUG DataSourceTransactionManager:329 - Committing JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162]
DEBUG DataSourceTransactionManager:390 - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8ef162] after transaction

從運行結(jié)果可以發(fā)現(xiàn)areaService.addArea()回滾了(本來就沒有提交內(nèi)容),goodService.addGood()的內(nèi)容提交了。

注意只有運行時異常以及rollbakcFor指定的異常才會回滾。

到此這篇關(guān)于關(guān)于spring中事務(wù)的傳播機制的文章就介紹到這了,更多相關(guān)spring事務(wù)的傳播機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Jmeter線程組的設(shè)置方法

    詳解Jmeter線程組的設(shè)置方法

    本文主要介紹了Jmeter線程組的設(shè)置方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • mybatis in查詢條件過長的解決方案

    mybatis in查詢條件過長的解決方案

    這篇文章主要介紹了mybatis in查詢條件過長的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring JDBC的使用方法詳解

    Spring JDBC的使用方法詳解

    這篇文章主要介紹了Spring JDBC的使用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • javaweb實戰(zhàn)之商城項目開發(fā)(二)

    javaweb實戰(zhàn)之商城項目開發(fā)(二)

    這篇文章主要針對javaweb商城項目開發(fā)進行實戰(zhàn)演習,利用mybatis創(chuàng)建DAO層,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • mybatis中的一級緩存深入剖析

    mybatis中的一級緩存深入剖析

    這篇文章主要介紹了mybatis中的一級緩存深入剖析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Java并發(fā)編程學習之ThreadLocal源碼詳析

    Java并發(fā)編程學習之ThreadLocal源碼詳析

    這篇文章主要給大家介紹了關(guān)于Java并發(fā)編程學習之源碼分析ThreadLocal的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-06-06
  • Java 深入淺出講解代理模式

    Java 深入淺出講解代理模式

    代理模式是Java常見的設(shè)計模式之一。所謂代理模式是指客戶端并不直接調(diào)用實際的對象,而是通過調(diào)用代理,來間接的調(diào)用實際的對象
    2022-03-03
  • resty的緩存技術(shù)設(shè)計及使用

    resty的緩存技術(shù)設(shè)計及使用

    這篇文章主要為大家介紹了resty緩存技術(shù)的設(shè)計及使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)組件使用案例

    Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)

    這篇文章主要介紹了Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)組件使用案例,需要的朋友可以參考下
    2014-10-10
  • 解析java中super的用法分析

    解析java中super的用法分析

    本篇文章是對java中super的用法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05

最新評論

辽源市| 尚志市| 南投县| 枣强县| 弥渡县| 衡南县| 舒兰市| 宁城县| 梓潼县| 建德市| 偏关县| 东乡县| 永和县| 淮滨县| 灌南县| 安平县| 东宁县| 禹州市| 张家口市| 稻城县| 化隆| 丰都县| 永川市| 达日县| 莲花县| 宁国市| 晋城| 张家口市| 绥中县| 上饶市| 青田县| 海林市| 宁城县| 肥乡县| 普陀区| 五河县| 萝北县| 郸城县| 江口县| 乌拉特后旗| 金华市|