Spring事务控制
事务定义
-
访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
-
事务特性:
- Atomicity:事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。
- Consistency:几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致
- Isolation:事务的执行不受其他事务的干扰
- Durability:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障
-
数据库事务实现的原理:
- 事务的ACID的实现是由关系型数据库 (DBMS)来实现的,DBMS采用日志来实现原子性,一致性与持久性,对于事务的隔离性采用锁机制来实现。
-
事务隔离等级不同造成的问题:
- 脏读:读取到其他事务未提交的事务
- 解决方案:提升隔离级别为Read Committed
- 原理:使用表级读锁
- 不可重复读:读取到的一条记录,多次读取到的结果不同
- 解决方案:提升隔离级别为Repeatable Read 可重复读
- 原理:使用行级写锁
- 幻读:在读取过程中数据的条目发生了变化
- 解决方案:提升隔离级别为Serializable
- 原理:表级写锁
- 脏读:读取到其他事务未提交的事务
-
Mysql的InnoDB锁机制(悲观锁)
- 共享锁/读锁:允许一个事务读取一行,阻止其他事务修改该数据
- 排他锁/写锁:其他事务不能读与写该数据
Spring事务管理
-
J2EE使用分层设计思想,在业务层对一组逻辑的代码进行事务管理
-
Spring为业务成提供了整套的事务解决方案:
- PlatformTransactionManager平台事务管理器
- TransactionDefinition事务定义
- TransactionStatus事务状态
-
平台事务管理器的分类
- DataSourceTransactionManager
- 适用于Spring JDBC或MyBatis
- PlatformTransactionManager对象定义了事务的基本操作:
- 获得事务:TransactionStatus getTransaction(TransactionDefinition definition)
- 提交事务:void commit(TransactionStatus status)
- 回滚事务:void rollback(TransactionStatus status)
- TransactionDefinition事务定义对象
- 获取事务名称:String getName()
- 获取事务读写属性:boolean isReadOnly()
- 获取事务隔离级别:int getIsolationLevel()
- 获取事务超时时间:int getTimeout()
- 获取事务传播行为特征:int getPropagationBehavior()
- TransactionStatus事务状态对象
- 获取事务是否处于新开启事务状态:boolean isNewTransaction()
- 获取事务是否处于已完成状态:boolean isCompleted()
- 获取事务是否处于回滚状态:boolean isRollbackOnly()
- 刷新事务状态:void flush()
- 获取事务是否具有回滚存储点:boolean hasSavepoint()
- 设置事务处于回滚状态:void setRollbackOnly()
- HibernateTransactionManager
- 适用于Hibernate3.0及以上版本
- DataSourceTransactionManager
-
使用Spring的AOP实现事务管理
- 编程式事务:
- 编写切面程序
public Object transationMoniter(ProceedingJoinPoint pjp) throws Throwable { // 获得事务管理器对象 PlatformTransactionManager ptm=new DataSourceTransactionManager(dataSource); // 获得默认事务定义对象 TransactionDefinition td=new DefaultTransactionDefinition(); // 获得事务状态对象 TransactionStatus transactionStatus = ptm.getTransaction(td); // 执行原来方法 Object proceed = pjp.proceed(); //提交事务 ptm.commit(transactionStatus); // 返回结果 return proceed; }
- 配置aop的xml文件
<aop:config > <aop:pointcut id="pt" expression="execution( public * com.itheima.service.impl.AccountServiceImpl.transfer(..))"/> <aop:aspect ref="txAdvice"> <aop:around method="transationMoniter" pointcut-ref="pt"></aop:around> </aop:aspect> </aop:config>
-
声明式事务:
-
配置数据库连接池
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
-
配置事务管理器(PlatformTransactionManager)
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
-
配置事务通知类
<tx:advice id="txAd" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" read-only="false" /> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice>
-
配置aop的切入点与切面的方法
<aop:config> <aop:pointcut id="pt" expression="execution(public * com.wx.service..*(..))"/> <aop:advisor advice-ref="txAd" pointcut-ref="pt"/> </aop:config>
-
-
tx:methord标签属性
<tx:method name="*" 待添加事务的方法名表达式(支持*号通配符),例如get* 、* 、…… read-only="false" 设置事务的读写属性,true为只读,false为读写 timeout="-1" 设置事务超时时长,单位秒 isolation="DEFAULT" 设置事务隔离级别,该隔离级设定是基于Spring的设定,非数据库端 no-rollback-for="" 设置事务中不回滚的异常,多个异常间使用,分割 rollback-for="" 设置事务中必回滚的异常,多个异常间使用,分割 propagation="REQUIRED" 设置事务的传播行为 />
- 编程式事务:
-
事务传播行为propagation
-
事务管理员:管理事务的事务
-
事务协调员:使用者本身需要执行的事务比如crud
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2B2NsTVE-1595069819382)(F:\MarkDownOnte\学习笔记\Spring\assets\1595055067983.png)]
-
使用注解配置事务
-
名称:@Transactional
-
类型:方法注解,类注解,接口注解
@Transactional( readOnly = false, timeout = -1, isolation = Isolation.DEFAULT, rollbackFor = {ArithmeticException.class, IOException.class}, noRollbackFor = {}, propagation = Propagation.REQUIRES_NEW )
-
xml中配置
<tx:annotation-driven transaction-manager="txManager"/> // 开启注解驱动与指定事务管理器
-
在配置类中开启事务支持
@EnableTransactionManagement
模板对象 spring-jdbc-template
-
spring提供的模板对象
- TransactionTemplate
- JdbcTemplate
- RedisTemplate
- RabbitTemplate
- JmsTemplate
- HibernateTemplate
- RestTemplate
-
jdbcTemplat
-
redisTemplate整合jeids
@Value("${redis.host}") private String hostName; @Value("${redis.port}") private Integer port; // @Value("${redis.password}") // private String password; @Value("${redis.maxActive}") private Integer maxActive; @Value("${redis.minIdle}") private Integer minIdle; @Value("${redis.maxIdle}") private Integer maxIdle; @Value("${redis.maxWait}") private Integer maxWait; @Bean //配置RedisTemplate public RedisTemplate createRedisTemplate(RedisConnectionFactory redisConnectionFactory){ //1.创建对象 RedisTemplate redisTemplate = new RedisTemplate(); //2.设置连接工厂 redisTemplate.setConnectionFactory(redisConnectionFactory); //3.设置redis生成的key的序列化器,对key编码进行处理 RedisSerializer stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setHashKeySerializer(stringSerializer); //4.返回 return redisTemplate; } @Bean //配置Redis连接工厂 public RedisConnectionFactory createRedisConnectionFactory(RedisStandaloneConfiguration redisStandaloneConfiguration,GenericObjectPoolConfig genericObjectPoolConfig){ //1.创建配置构建器,它是基于池的思想管理Jedis连接的 JedisClientConfiguration.JedisPoolingClientConfigurationBuilder builder = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder(); //2.设置池的配置信息对象 builder.poolConfig(genericObjectPoolConfig); //3.创建Jedis连接工厂 JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration,builder.build()); //4.返回 return jedisConnectionFactory; } @Bean //配置spring提供的Redis连接池信息 public GenericObjectPoolConfig createGenericObjectPoolConfig(){ //1.创建Jedis连接池的配置对象 GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); //2.设置连接池信息 genericObjectPoolConfig.setMaxTotal(maxActive); genericObjectPoolConfig.setMinIdle(minIdle); genericObjectPoolConfig.setMaxIdle(maxIdle); genericObjectPoolConfig.setMaxWaitMillis(maxWait); //3.返回 return genericObjectPoolConfig; } @Bean //配置Redis标准连接配置对象 public RedisStandaloneConfiguration createRedisStandaloneConfiguration(){ //1.创建Redis服务器配置信息对象 RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); //2.设置Redis服务器地址,端口和密码(如果有密码的话) redisStandaloneConfiguration.setHostName(hostName); redisStandaloneConfiguration.setPort(port); // redisStandaloneConfiguration.setPassword(RedisPassword.of(password)); //3.返回 return redisStandaloneConfiguration; }
-
RedisTemplate的API
- opsForValue 操作String
- opsForHash 操作Hash
- opsForList 操作List
tPort(port);
// redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
//3.返回
return redisStandaloneConfiguration;
}
-
RedisTemplate的API
- opsForValue 操作String
- opsForHash 操作Hash
- opsForList 操作List
- opsForSet 操作Set