Spring-Transaction-Annotaion:以注解方式配置的声明式事务
Spring-Transaction-XML:以XML方式配置的声明式事务
编程式事务(略)
声明式事务
pom.xml需要引入:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjrtartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
Springboot 引入 事务控制配置文件(applicationContext-db.xml)
ApplicationContextConfig.java
package top.simba1949;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author [email protected]
* @date 2018/8/25 8:01
*/
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
applicationContext.xml 和 applicationContext-db.xml融合到一个spring容器中
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="applicationContext-db.xml">import>
beans>
applicationContext-db.xml
<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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<aop:config>
<aop:pointcut id="aopPoincut" expression="execution(* top.simba1949.service.impl.*.*(..))">aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="aopPoincut">aop:advisor>
aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="modify*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="java.lang.Exception"/>
<tx:method name="query*" read-only="true">tx:method>
<tx:method name="select*" read-only="true">tx:method>
<tx:method name="find*" read-only="true">tx:method>
tx:attributes>
tx:advice>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:mybatis-config.xml">property>
<property name="mapperLocations">
<array>
<value>classpath*:top/simba1949/mapper/*Mapper.xmlvalue>
array>
property>
<property name="typeAliasesPackage" value="top.simba1949.common">property>
bean>
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="top.simba1949.mapper">property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">property>
bean>
beans>
mybatis-config.xml
<configuration>
configuration>
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=19491001
application.properteis
server.port=8083
#mysql设置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=19491001
#表示打印出sql语句
logging.level.com.shyroke.mapper=debug
#mybatis配置
mybatis.mapper-locations=classpath*:top/simba1949/mapper/*Mapper.xml
mybatis.type-aliases-package=top.simba1949.common
Application.java
package top.simba1949;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author [email protected]
* @date 2018/8/25 8:01
* @MapperScan(basePackages = "top.simba1949.mapper")扫描mapper包
*/
@SpringBootApplication
@MapperScan(basePackages = "top.simba1949.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
CountryServiceImpl.java
@Transactional(rollbackFor = Exception.class)即可开启注解
package top.simba1949.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.simba1949.common.CountryCommon;
import top.simba1949.mapper.CountryMapper;
import top.simba1949.service.CountryService;
/**
* @author [email protected]
* @date 2018/8/24 23:22
*/
@Service
public class CountryServiceImpl implements CountryService {
@Autowired
private CountryMapper countryMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public int insert(CountryCommon countryCommon) {
int i = countryMapper.insert(countryCommon);
return i;
}
}
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.DEFAULT,
timeout = -1,
readOnly = false,
rollbackFor = Exception.class,
noRollbackFor = Exception.class
)
属性 | 含义 | 默认值 |
---|---|---|
propagation,定义事务的生命周期 | REQUIRED:方法A调用式没有事务新建一个事务,当方法A调用另一个方法B时,方法B将使用相同的事务;如果方法B发生异常需要回滚的时候,整个事务数据回滚 | REQUIRED |
REQUIRED_NEW:方法A和方法B,在方法调用的时候无论是否有事务都开启一个新事务;这样如果方法B有异常不会导致方法A的数据回滚 | ||
NESTED:和REQUIRED_NEW类似,但是支持JDBC,不支持JPA和Hibernate | ||
NOT_SUPPORTED:强制方法不在事务中执行,若有事务,在方法调用结束阶段事务将被挂起 | ||
NEVER:强制方法不在事务中执行,若有事务则抛出异常 | ||
MANDATORY:强制方法在事务中执行,若无事务则抛出异常 | ||
isolation:(隔离)决定了事务的完整性,处理在多事务对相同数据的处理机制 | READ_UNCOMMITTED:对于在A事务里修改了一条记录但是没有提交事务,在B事务可以读取到修改后的记录。可导致脏读,可不重复读以及幻读 | DEFAULT(使用当前数据库默认的级别,oracle、sql server默认为READ_COMMITTED,mysql默认REPEATABLE_READ) |
READ_COMMITTED:只有当事务A里修改了一条记录且提交事务之后,B事务才可以读取到提交后的记录;阻止脏读,但是可导致不可重复读和幻读 | ||
REPEATABLE_READ:不仅能实现READ_COMMITTED的功能,而且还能阻止当A事务读取了一条记录,B事务将不允许修改这条记录;阻止了脏读,不可重复读,但是可导致幻读 | ||
SERIALIZABLE:此级别下事务是顺序执行的,可以避免上述级别的缺陷,但是开销比较大 | ||
timeout | timeout事务过期时间,默认为当前数据库的事务过期时间 | |
readonly | 指定当前事务是否是只读事务 | false |
rollbackfor | 指定哪个或者哪些异常可以引起事务回滚 | Throwable的子类 |
noRollbackfor | 指定哪个或者哪些异常不可以引起事务回滚 | Throwable的子类 |