Spring事务实现

 

▶ 1 ◀   声明式事务(纯xml配置)

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

	<!-- 包扫描:将配置了@Controller、@Service、@Repository、@Compoment注解的组件添加到Spring容器 -->
	<context:component-scan base-package="com.mote" />

	<!-- 配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<!-- mysql连接驱动jar版本为6.06,驱动类由com.mysql.jdbc.Driver变为com.mysql.cj.jdbc.Driver -->
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://114.25.83.3:3306/mote" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</bean>

	<!-- 定义事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 配置事务特性 -->
	<tx:advice id="adviceRef" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- add*:匹配以add为开头的所有方法,符合此命名规则的方法作为一个事务。 
			REQUIRED:若当前没有事务,就新建一个事务,若存在一个事务中,加入该事务中。这是最常见的选择 -->
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="upd*" propagation="REQUIRED" />
			<tx:method name="get*" propagation="REQUIRED" />
			<tx:method name="*" read-only="true" rollback-for="Exception" />
		</tx:attributes>
	</tx:advice>

	<!-- 配置切点(需要加事务类、方法),并切入事务 -->
	<aop:config>
		<!-- 配置事务切点 -->
		<aop:pointcut id="cutPoint"
			expression="execution(public * com.mote.service.*.*(..))" />
		<!-- 切入事务 -->
		<aop:advisor pointcut-ref="cutPoint" advice-ref="adviceRef" />
	</aop:config>

</beans>

▶ 2 ◀   注解式事务(半xml半注解)

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

	<!-- 包扫描:将配置了@Controller、@Service、@Repository、@Compoment注解的组件添加到Spring容器 -->
	<context:component-scan base-package="com.mote" />

	<!-- 配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<!-- mysql连接驱动jar版本为6.06,驱动类由com.mysql.jdbc.Driver变为com.mysql.cj.jdbc.Driver -->
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://114.25.83.3:3306/mote" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</bean>

	<!-- 定义事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 开启注解事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

 

事务注解  @Transactional 

● @Transactional标注在类上面, 表示类中所有方法都进行事物控制

● @Transactional标注在方法上面,表示该方法受事务控制

● 当@Transactional标注在类上,但是该类中的某些方法又不需要事务控制,可以在方法上面标注 @Transactional(propagation =Propagation.NOT_SUPPORTED) 使方法上的事务消失

 

▶ 3 ◀   注解式事务(纯注解),只有在纯注解开发时才会使用

Spring配置类(相当于applicationContext.xml)

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement// 开启基于注解的事务管理功能
@Configuration// 标注这是一个配置类
@ComponentScan("com.mote")// 包扫描,将@Controller,@Service,@Repostory,@Compoment组件注册到Spring容器
public class MainConfig {

	@Bean// 配置数据源
	public BasicDataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setUrl("jdbc:mysql://114.215.83.3:3306/debo");
		dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		dataSource.setUsername("root");
		dataSource.setPassword("123456");
		return dataSource;
	}

	@Bean// 配置事务管理器
	public DataSourceTransactionManager dataSourceManager(
			BasicDataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

}

 

使用 @Transactional 进行事务控制

 

附录 ◀ :xml配置事务切点时,切入点表达式的书写规则

表达式模板:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

  修饰符,一般省略

    public 公共方法

               * 任意

  返回值,不能省略

    void 返回没有值

    String 返回值字符串

    * 任意

  

    com.zby.service  固定包

    com.zby.oa.*.service oa包下面子包 (例如:com.zby.oa.flow.service)

    com.zby.oa..   oa包下面的所有子包(含自己)

    com.zby.oa.*.service.. oa包下面任意子包,固定目录service,service目录任意包

  

    UserServiceImpl 指定类

    *Impl 以Impl结尾

    User* 以User开头

    * 任意

  方法名,不能省略

    addUser 固定方法

    add* 以add开头

    *Do 以Do结尾

    * 任意

  (参数)

    () 无参

    (int) 一个整型

    (int ,int) 两个

    (..) 参数任意

  throws ,可省略,一般不写