Java《事务》(入门)

目录

一、什么是事务?

二、为什么要使用事务?

三、事务的四大属性(ACID)

四、事务的种类

五、JDBC事务

1.sql语句中

2.JDBC中

3.事务的四个隔离级别

六、spring事务

1.Spring 事务的七种传播属性


一、什么是事务?

事务就是你对数据的一次操作,这一次操作中可以是一句简单的添加语句,也可以是对多张表的多次操作

二、为什么要使用事务?

以为它安全,为什么安全?比如张三给李四转账,我们要从张三的账户扣钱,往李四的账户加钱,但是在执行时,张三扣钱的sql执行成功了,李四加钱的sql出错了,这时会出现张三的钱少了,李四的钱没加。怎么解决这种隐患呢?本次交易就是一个事务,在事务中,所有的sql要么都成功,要么都失败,这就到了事务的四个特性。

三、事务的四大属性(ACID)

  1. 原子性(atomicity):一个事务中有多个sql,这些sql要么都做,要么都不做;
  2. 一致性(consistency):一个事务中有多个sql,这些sql要么都成功,要么都失败,不存在上面的情况(张三钱少了,李四钱没变);
  3. 隔离性(isolation):顾名思义,就是各个事务之间相互隔离,互不影响
  4. 持久性(durability):事务一旦提交,数据便保留在数据库中。

四、JDBC事务

1.sql语句中

还是拿demo1表

查询:

开启事务,修改name,查看表信息 

 事务回滚,信息查看

 总结:

开启事务:START TRANSACTION 

提交事务:COMMIT;

回滚事务:ROLLBACK;

2.JDBC中

意思还是sql中的意思,只不过换了种形式

Connection connection;
try{
    //创建链接
    connection = JDBCUtil.getConnection();
    //开启手动提交事务(关闭自动提交事务)
    connection.setAutoCommit(false);
    //自己的数据操作
    *** ***
    //提交事务
    connection.commit();
}catch(Exception e) {
    e.printStackTrace();
    //异常回滚事务
    connection.rollback();
}

提出问题:

在sql语句表达事务时发现一个问题,在开启事务后对数据进行修改,查看数据是我们修改过的,回滚后再看就有回到了修改前,那么问题来了?

问题一:

这个问题叫脏读,因为读取到了没有提交的数据,这种数据叫脏数据,所以叫脏读

问题二:

这个问题叫不可重复读 ,它与脏读的区别在于没有脏数据

问题三:

 这个问题叫幻读,它与可重复读的区别是:不可重复读是数据变没变,而幻读是输出存在不存在问题

问题总结:

脏读和不可重复读的区别在于脏数据

不可重复读和幻读的区别在于一个是数据的变化问题,一个是数据的存在问题

这些问题的出现又产生了另一个知识点:事务的隔离级别

3.事务的四个隔离级别

事务的隔离级别由低到高分别是

1.Read uncommitted:读未提交

最低级,顾名思义,就是能够读到未提交事务的数据,所以上面的问题都会发生

2.Read committed  :读已提交

只能读到已经提交事务的数据,可避免脏读

3.Repeatable read 可重复读
事务开启后不在允许修改操作,可避免脏读,不可重复读

4.Serializable :序列化

最高级事务,开启后事务按顺序执行,可避免以上问题(脏读、不可重复读、幻读)

Mysql 默认:可重复读
Oracle 默认:读已提交

五、spring事务

1.Spring 事务的七种传播属性

required、supports、mandatory、requires_new、not supported、never、nested

什么是Spring 事务的传播属性?

当多个事务同时存在的时候,spring对这些事务的处理叫事务的传播属性

所属接口TransactionDefinition

源码如下

 说明:

名称  解释
PROPAGATION_REQUIRED
支持当前事务,如果当前没有事务,就新建一个事务。(默认且常见)
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

 使用:

1.spring配置

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource ">
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入连接池对象 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

	<!-- 注解扫描 -->
    <context:component-scan base-package="com.test.spring.demo4"/>
	<!-- 开启注解事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>

使用

@Transactional(propagation = Propagation.REQUIRED)
public class XxxServiceImpl implements XxxService {

    @Autowired
    private XxxDao xxxDao;

    @Override
    public void xxx(...) {
        //TODO 实现业务
    }

}

其他使用方式,看Spring中使用事务的常用几种方式_morningcat2018的博客-CSDN博客_spring事务使用

六、分布式事务

有空再总结... ...

不足或错误之处还望指出,定加修改,共同进步!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值