数据库的事务以及Spring管理事务

本文介绍了数据库事务的ACID特性、四大隔离级别及其可能引发的问题,并详细讲解了Spring如何管理事务,包括PlatformTransactionManager接口、不同事务传播行为以及Spring的XML和注解配置方式。
摘要由CSDN通过智能技术生成

事务:
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
操作:
1. 开启事务: start transaction;
2. 回滚:rollback;
3. 提交:commit;

CREATE TABLE account (
			id INT PRIMARY KEY AUTO_INCREMENT,
			NAME VARCHAR(10),
			balance DOUBLE
		);
		-- 添加数据
		INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
        SELECT * FROM account;
		UPDATE account SET balance = 1000;
		-- 张三给李四转账 500 元
		
		-- 0. 开启事务
		START TRANSACTION;
		-- 1. 张三账户 -500
		
		UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
		-- 2. 李四账户 +500
		-- 出错了...
		UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
		
		-- 发现执行没有问题,提交事务
		COMMIT;
		
		-- 发现出问题了,回滚事务
		ROLLBACK;

事务提交的两种方式:
* 自动提交:
* mysql就是自动提交的
* 一条DML(增删改)语句会自动提交一次事务。
* 手动提交:
* Oracle 数据库默认是手动提交事务
* 需要先开启事务,再提交

事务的四大特征:
ACID

  1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
  2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
  3. 隔离性:多个事务之间。相互独立。
  4. 一致性:事务操作前后,数据总量不变

事务隔离级别
概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。

存在问题:
1. 脏读:一个事务,读取到另一个事务中没有提交的数据
2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

隔离级别:(四种)
1. read uncommitted:读未提交
* 产生的问题:脏读、不可重复读、幻读
2. read committed:读已提交 (Oracle)
* 产生的问题:不可重复读、幻读
3. repeatable read:可重复读 (MySQL默认)
* 产生的问题:幻读
4. serializable:串行化
* 可以解决所有的问题

  • 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
    * 数据库查询隔离级别:
    * select @@tx_isolation;
    * 数据库设置隔离级别:
    * set global transaction isolation level 级别字符串;

其实我们在开发中大多数是使用spring来管理事务,接下来我们聊一聊关于spring和事务。

Spring中的事务控制

PlatformTransactionManager
接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法:
获取事务状态信息:
TransactionStatus getTransaction(TransactionDefinition definition)
提交事务:
void commit(TransactionStatus status)
回滚事务:
void rollback(TransactionStatus status)

真正管理事务的对象
org.springframework.jdbc.datasource.DataSourceTransactionManager 使用 Spring JDBC 或 iBatis 进行持久化数据时使用 org.springframework.orm.hibernate5.HibernateTransactionManager 使用 Hibernate 版本进行持久化数据时使用

事务的传播行为(七种)
REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选 择(默认值)
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
NEVER:以非事务方式运行,如果当前存在事务,抛出异常
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作。

Spring中事务基于XML的配置
第一步在配置文件中配置业务层和持久层对

<!-- 配置 service --> 
<bean id="accountService" class="com.service.impl.AccountServiceImpl">  
<property name="accountDao" ref="accountDao"></property> 
</bean>

<!-- 配置 dao -->
<bean id="accountDao" class="com.dao.impl.AccountDaoImpl"> 
<!-- 注入 dataSource -->  
<property name="dataSource" ref="dataSource"></property> 
</bean>

第二步配置事务管理器

<!-- 配置一个事务管理器 --> 
<bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入 DataSource -->  
<property name="dataSource" ref="dataSource"></property> </bean> 

第三步配置事务的通知引用事务管理器

<!-- 事务的配置 --> 
<tx:advice id="txAdvice" transaction-manager="transactionManager">
 </tx:advice> 

第四步配置事务的属性

<!--在 tx:advice 标签内部 配置事务的属性 --> 
<tx:attributes> 
<!-- 指定方法名称:是业务核心方法   
            read-only:是否是只读事务。默认 false,不只读。  
            isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。   
            propagation:指定事务的传播行为。  
            timeout:指定超时时间。默认值为:-1。永不超时。  
            rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。 没有默认值,任何异常都回滚。  
            no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回 滚。没有默认值,任何异常都回滚。  --> 
<tx:method name="*" read-only="false" propagation="REQUIRED"/>  
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/> 
</tx:attributes> 

第五步配置AOP切入点表达式

<!-- 配置 aop --> 
 <aop:config> 
 <!-- 配置切入点表达式 -->  
        <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"/> 
 </aop:config> 

第六步配置切入点表达式和事务通知的对应关系

<!-- 在 aop:config标签内部:建立事务的通知和切入点表达式的关系 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/> 

Spring中事务基于注解配置
第一步配置事务管理器并注入数据源

<!-- 配置事务管理器 -->  
<bean id="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
 <property name="dataSource" ref="dataSource">
 </property>  
 </bean>

第二步在业务层使用@Transactional 注解

@Transactional(readOnly=false,propagation=Propagation.REQUIRED)

第三步在配置文件中开启 spring 对注解事务的支持

<!-- 开启 spring 对注解事务的支持 --> 
<tx:annotation-driven transaction-manager="transactionManager"/> 

SQL分类:
1. DDL:操作数据库和表
2. DML:增删改表中数据
3. DQL:查询表中数据
4. DCL:管理用户,授权

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值