1.事务管理
-
原子性(Atomicity):
指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
-
一致性(Consistency):
事务前后数据的完整性必须保持一致。
-
隔离性(Isolation):
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
-
持久性(Durability):
事务的运行
- 开启事务
- 进行业务操作
- 没有发生异常,提交事务
- 发生异常,进行事务回滚
2.声明式事务管理
2.1 实现步骤
-
创建配置事务管理器
DataSourceTransactionManage (针对JdbcTemplate或Mybatis)
-
开启事务
@EnableTransactionManagement 或者配置 < tx:annotation-driven/>
-
@Transactional
(1)基于注解实现
配置类:SpringConfig.java
@Configuration
@ComponentScan(basePackages = {"com.potato"})
@EnableTransactionManagement // 2.开启事务注解
public class SpringConfig {
//1.创建配置事务管理器 DataSourceTransactionManager
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "dataSource")
public DataSource createDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.MysqL.jdbc.Driver");
dataSource.setUrl("jdbc:MysqL://127.0.0.1:3306/Spring5");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
@Bean(name = "jdbcTemplate")
public JdbcTemplate createDataSource(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
}
需要事务处理的类:BankServiceImpl.java
//3.在需要进行事务处理的类或者方法上添加事务注解
@Transactional
@Override
public Integer transferAccounts(String saveAccount, String takeAccount, int money) {
Integer take = bankDao.take(takeAccount, money);
Integer save = bankDao.save(saveAccount, money);
return take == save ? (take != 0 ? 1 : 0) : 0;
}
(2)基于xml配置文件实现
<context:component-scan base-package="com.potato"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.driver.jdbc.MysqL"/>
<property name="url" value="jdbc:MysqL://127.0.0.1:3306/Spring5"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<!-- 1.创建事务管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 2.开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
2.2 Spring事务管理API :PlatformTransactionManager接口
PlatformTransactionManager:事务管理的接口,有多个不同的实现类分别针对不同的数据处理框架
DataSourceTransactionManager :JdbcTemplate、Mybatis
HibernateTransactionManager:Hibernate
2.3 @Transactional 相关参数
propagation:事务传播行为
isolation:事务隔离级别
timeout:超时时间
readOnly:是否只读
rollbackFor:发生指定的异常则回滚
norollbackFor:发生指定的异常则不回滚
2.4 传播行为:propagation
传播属性 | 解析 |
---|---|
required(默认) | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中, 就继续使用该事务。这是最常见的选择。 |
REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
nesTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务, 则执行与required类似的操作。 |
2.5 隔离级别:isolation
-
不考虑隔离性 则会产生以下三个问题
-
隔离级别参数
属性值 脏读 不可重复读 幻读 READ_UNCOMMITTED(读未提交) 有 有 有 READ_COMMITTED(读以提交) 无 有 有 REPEATABLE_READ(可重复读) (默认) 无 无 有 SERIALIZABLE(串行化) 无 无 无
2.6 其他参数
-
timeout:超时时间 秒为单位
事务在一定时间内进行提交,如果不提交则进行回滚
-
readOnly:是否只读
(1)1.读:查询操作 2.写:增删改操作
(2)默认值为 false, 表示可以增删改查
(3)设置为true 则是只读操作
-
rollbackFor:回滚
(1)设置出现哪些异常需要进行事务回滚
-
norollbackFor:不回滚
(1)设置出现哪些异常不需要进行事务回滚
3.编程式事务管理
-
实现步骤
1.配置事务管理器
2.配置通知
3.配置切入点和切面
spring-config.xml
<context:property-placeholder location="druid.properties"/> <context:component-scan base-package="com.potato"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driverClass}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg ref="dataSource"/> </bean> <!-- 1 创建事务管理器--> <bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 2 配置通知--> <tx:advice id="txAdvice"> <!-- 2.1 配置事务参数--> <tx:attributes> <!-- 2.2 指定哪种方法上添加事务 名字以transfer开头的方法添加事务--> <tx:method name="transfer*" propagation="required"/> </tx:attributes> </tx:advice> <!-- 3 配置切面--> <aop:config> <!-- 3.1 配置切入点--> <aop:pointcut id="pointcut01" expression="execution(* com.potato.service.BankService.*(..))"/> <!-- 3.2 配置切面--> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut01"/> </aop:config>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。