----- 方式一:基于注解@Transcation的事务编程步骤 -----
1、引入tx命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
2、配置事务管理器
(数据源dataSource需要在xml文件中定义好:<bean id="dataSource" class="..."></bean>)
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
3、启用事务注解
<tx:annotation-driven transaction-manager="transactionManager"/>
4、给需要使之成为事务的方法前加上@Transactional注解
Transactional注解的属性
1.propagation:指定事务的传播行为,默认值为REQUIRED
2.isolation:指定事务的隔离级别,常用取值是READ_COMMITTED
3.noRollbackFor:抛出指定的异常时不回滚
4.readOnly:指定事务是否只读,表示该事务只读取数据,不更新数据
5.timeout=X(X的单位为秒):如果X秒内事务没有执行完成,抛出异常,强制停止事务
@Transactional(propagation=Propagation.REQUIRES_NEW,
isolation=Isolation.READ_COMMITTED,
noRollbackFor=UserAccountException.class,
readOnly=false,
timeout=3
)
事务的传播属性
当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播。 例如: 方法可能继续在现有事务中运行, 也可能开启一个新事务, 并在自己的事务中运行.
事务的传播行为可以由传播属性指定. Spring 定义了7种类传播行为。常见的有两种:
1、 REQUIRES传播行为:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的的事务,并在自己的事务内运行
2、 REQUIRES_NEW传播行为:它表示该方法必须启动一个新事务, 并在自己的事务内运行. 如果有事务在运行, 就应该先挂起它
例子:A、B两种书的库存都充足,单价分别为80元和70元。甲账户余额100元。
买一本书的方法(此方法具有@Transactional注解) public void purchase(String username, String isbn);
买若干本书的方法(此方法也具有Transactional注解,该方法是通过逐一调用purchase()实现的) public void checkout(String username, List<String> isbns)
此时调用checkout("甲",Arrays.asList("A","B"))方法
如果传播行为是REQUIRES,则两本书都不能购买成功。
如果传播行为是REQUIRES_NEW,则A书购买成功,B书购买失败。
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
-----方式二: 基于xml文件配置的事务编程步骤 -----
<!-- 配置事务管理器 -->
<-- (数据源dataSource需要在xml文件中定义好:<bean id="dataSource" class="..."></bean>) -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 要声明为事务的方法的名字:tx:method name="xxx方法" -->
<tx:method name="purchase" propagation="REQUIRED"/>
<!-- tx:method 属性还有timeout等等
<tx:method name="purchase" timeout="3" no-rollback-for="XxxException"/>
-->
<!-- 可以使用“*”号做通配符,如下:
<tx:method name="get*" propagation="REQUIRES_NEW"/>
-->
</tx:attributes>
</tx:advice>
<!-- 配置事务切入点,以及把事务切入点和事务属性关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))"
id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
1、引入tx命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
2、配置事务管理器
(数据源dataSource需要在xml文件中定义好:<bean id="dataSource" class="..."></bean>)
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
3、启用事务注解
<tx:annotation-driven transaction-manager="transactionManager"/>
4、给需要使之成为事务的方法前加上@Transactional注解
Transactional注解的属性
1.propagation:指定事务的传播行为,默认值为REQUIRED
2.isolation:指定事务的隔离级别,常用取值是READ_COMMITTED
3.noRollbackFor:抛出指定的异常时不回滚
4.readOnly:指定事务是否只读,表示该事务只读取数据,不更新数据
5.timeout=X(X的单位为秒):如果X秒内事务没有执行完成,抛出异常,强制停止事务
@Transactional(propagation=Propagation.REQUIRES_NEW,
isolation=Isolation.READ_COMMITTED,
noRollbackFor=UserAccountException.class,
readOnly=false,
timeout=3
)
事务的传播属性
当事务方法被另一个事务方法调用时, 必须指定事务应该如何传播。 例如: 方法可能继续在现有事务中运行, 也可能开启一个新事务, 并在自己的事务中运行.
事务的传播行为可以由传播属性指定. Spring 定义了7种类传播行为。常见的有两种:
1、 REQUIRES传播行为:如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的的事务,并在自己的事务内运行
2、 REQUIRES_NEW传播行为:它表示该方法必须启动一个新事务, 并在自己的事务内运行. 如果有事务在运行, 就应该先挂起它
例子:A、B两种书的库存都充足,单价分别为80元和70元。甲账户余额100元。
买一本书的方法(此方法具有@Transactional注解) public void purchase(String username, String isbn);
买若干本书的方法(此方法也具有Transactional注解,该方法是通过逐一调用purchase()实现的) public void checkout(String username, List<String> isbns)
此时调用checkout("甲",Arrays.asList("A","B"))方法
如果传播行为是REQUIRES,则两本书都不能购买成功。
如果传播行为是REQUIRES_NEW,则A书购买成功,B书购买失败。
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
-----方式二: 基于xml文件配置的事务编程步骤 -----
<!-- 配置事务管理器 -->
<-- (数据源dataSource需要在xml文件中定义好:<bean id="dataSource" class="..."></bean>) -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 要声明为事务的方法的名字:tx:method name="xxx方法" -->
<tx:method name="purchase" propagation="REQUIRED"/>
<!-- tx:method 属性还有timeout等等
<tx:method name="purchase" timeout="3" no-rollback-for="XxxException"/>
-->
<!-- 可以使用“*”号做通配符,如下:
<tx:method name="get*" propagation="REQUIRES_NEW"/>
-->
</tx:attributes>
</tx:advice>
<!-- 配置事务切入点,以及把事务切入点和事务属性关联起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))"
id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>