Spring事务

事务:事务是保证业务操作完整性的一种数据库机制。事务拥有四大特性:

**原子性(atomicity):**事务是一个不可分割的最小单元,要么全部提交,要么全部失败回滚。

一致性(consistency):指事务执行前后,数据从一个合法性状态变换到另外一个合法性状态

隔离性(isolation):事务的隔离性是指一个事务的执行不能被其他事务干扰。

持久性(durability):一个事务一旦被提交,它对数据库中数据的改变就是永久性的。

如何控制事务:

JDBC

Connection.setAutoCommit(false);
Connection.commit();
Connection.rollback();

Mybatis

Mybatis自动开启事务
sqlSession.commit(),底层调用的还是Connection.commit;
SqlSession.rollback(),底层调用的还Connection.rollback()

总结:控制事务的底层,都是通过Connection对象完成的。

Spring控制事务编码

XML形式

  • 依赖

    <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>5.1.12.RELEASE</version>
            </dependency>
    
  • 编码

    public interface UserService {
        void register(User user);
    }
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
        @Override
        public void register(User user) {
            userDao.save(user);
        }
    }
    
    <!--    连接池,获取Connection连接-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring?useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    
    <!--
    额外功能:
    transactionManager就是事务的额外功能,负责事务的提交或回滚,
    因为底层是Connection进行commit或rollback,所以注入连接池,便于快速获取Connection连接
    -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!--设置事务属性-->
    <tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 给register方法设置事务属性-->
            <tx:method name="register" isolation="DEFAULT" propagation="REQUIRED"/>
            <!-- 给除了register方法外的其他以modify为命名前缀的方法设置事务属性-->
            <tx:method name="modify*"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 切面:组长切入点和额外功能-->
    <aop:config>
        <!-- 切入点:给哪些方法加上事务-->
        <aop:pointcut id="pc" expression="execution(* edu.hzb.tx.xml.UserServiceImpl.*(..))"/>
        <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="pc"/>
    </aop:config>
    

注解形式

@Configuration
@ComponentScan("edu.hzb.tx.annotation")
@EnableTransactionManagement
public class Appconfig {

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring?useSSL=false");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
public interface UserService {
    void register(User user);
}

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void register(User user) {
        userDao.save(user);
    }
}

Spring事务属性

属性是描述物体特征的一系列值,比如人的身高、性别、体重。事务属性就是描述事务特征的一系列值。

事务属性包含:

  1. 隔离属性
  2. 传播属性
  3. 只读属性
  4. 超时属性
  5. 异常属性

隔离属性(isolation)

概念:描述了事务解决并发问题的特征。

  1. 什么是并发

    多个事务在同一时间,访问操作了相同的数据。

  2. 并发会产生哪些问题

    1. 脏写(脏写问题太严重,所有的隔离级别都可以解决脏写)
    2. 脏读
    3. 不可重复读
    4. 幻读
  3. 并发问题如何解决

    通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题。

数据库对隔离属性的支持

隔离属性MySQLOracle
READ_COMMITED支持支持
REPEATABLE_READ支持不支持
SERIALIAZBLE支持支持
Oracle不支持REPEATABLE_READ,采用的是多版本对比(乐观锁)的方式,解决不可重复读的问题。

默认的隔离属性

ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性。
MySQL:REPEATABLE_READ
Oracle:READ_COMMITED

对于隔离属性,推荐使用Spring指定的ISOLATION_DEFAULT,使用对应数据库的隔离级别。

传播属性(propagation)

**概念:**描述了事务解决嵌套问题的特征。

1. 什么叫事务的嵌套?
指的是一个打的事务中,包含了若干个小的事务。
2. 事务嵌套带来的问题?
大事务中嵌套了多个小的事务,彼此相互影响,最终导致外部大的事务丧失了事务的原子性。

传播属性的值及其用法

传播属性的值外部不存在事务外部存在事务用法备注
REQUIRED开启新的事务融合到外部事务中@Transational(propagation=Propagation.REQUIRED)增删改方法
SUPPORTS不开启事务融合到外部事务中@Transational(propagation=Propagation.SUPPORTS)查询方法
REQUIRES_NEW开启新的事务挂起外部事务,创建新的事务@Transational(propagation=Propagation.REQUIRES_NEW)日志记录方法中
NOT_SUPPORTED不开启事务挂起外部事务@Transational(propagation=Propagation.NOT_SUPPORTED)极其不常用
NEVER不开启事务抛出异常@Transational(propagation=Propagation.NEVER)极其不常用
MANDATORY抛出异常融合到外部事务中@Transational(propagation=Propagation.MANDATORY)极其不常用

默认的传播属性REQUIRED

推荐传播属性的使用方式

增删改方法:直接使用默认值REQUIRED

查询方法:显式指定传播属性的值为SUPPORTS

只读属性(readOnly)

针对只进行查询操作的业务方法,可以加入只读属性,提高运行效率。

默认值:false,可以改为true来使用只读属性

Transactional(readOnly=true)

超时属性(timeout)

指定事务等待的最长时间。

1. 为什么事务进行等待?
当前事务访问数据时,有可能访问的数据被别的事务进行加锁的的处理,那么当前事务就必须进行等待。
2. 等待时间单位:秒
3  如何使用:Transactional(timeout=2)
4. 超时属性的默认是-1,-1表示超时属性由对应的数据库设置。

异常属性(exception)

Spring事务处理过程中:

  • 默认对RuntimeException及其子类,采用的是回滚的策略。
  • 默认对Exception及其子类(排除RuntimeException及其子类),采用的是提交的策略。
@Transactional(rollbackFor = {java.lang.RuntimeException.class}, noRollbackFor = {java.lang.Exception.class})

学习哔哩哔哩《孙哥讲Spring5》视频所做的笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值