事务的概述
事务概念:
事务一般特指数据库事务(Database Transaction),是指作为一个程序执行单元执行的一系列操作,要么完全执行,要么完全不执行
事务特性:
- 原子性(atomicity)
一个事务是一个不可分割的工作单位
从结构上,保证事务只有两种状态:完全执行 和 完全不执行
- 一致性(consistency)
事务必须是数据库从一个一致性状态变到另一个一致性状态
从业务上,保证事务是合理的
- 隔离性(isolation)
一个事务的执行不能被其他事务干扰
并发的时候,两个事务之间不能相互干扰,相互影响
- 持久性(durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的
MySQL事务处理
基本语句
- MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
show engines; => 查看服务器支持的引擎
default-storage0engin = Innodb —my.ini => 修改默认引擎
- MySQL默认以自动提交(autocommit)模式运行
// 显示地开启一个事务begin(starttransaction)// 提交事务,并使已对数据库进行的所有修改变为永久性的commit// 回滚事务,并撤销正在进行的素哟有未提交的修改rollback
并发问题

解决方案:只能读取永久性数据,不能读取内存中的数据来解决

解决方案:通过锁行的方式解决

解决方案:通过锁表的方式解决
事务隔离级别

#隔离级别越高,处理并发事务执行的时候,效率越低
#所以,隔离级别并不是设置越高越好,而要根据需要合理设置
语句
// 查询默认隔离级别select @@transaction_isolation;// 设置当前会话隔离级别(注意没有中线)set session transaction isolation level read committed
JDBC事务处理
基本语句
- Connection接口
JDBC的事务处理是基于Connection的,JDBC通过Connection对象进行事务管理
JDBC默认事务处理行为是自动提交
- 事务相关方法
setAutoCommit => 设置自动提交
commit => 提交事务
rollaback => 回滚事务
package com.imooc.os.dao;import org.junit.Test;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;public class OrderTest {private String driver = "com.mysql.jdbc.Driver";private String url = "jdbc:mysql://localhost:3306/os?useUnicode=true&characterEncoding=utf8";private String userName = "root";private String password = "root";@Testpublic void addOrder(){try {Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}Connection connection = null;try {connection = DriverManager.getConnection(url,userName,password);// 设置不要自动提交connection.setAutoCommit(false);Statement statement = connection.createStatement();// 以下两个execute就封装成了一个事务statement.execute("insert into orders values('100002','100001',2,2499,now(),null,null,'刘备','1330000000','成都','待发货')");statement.execute("update products set stck=stock-2 where id='100001'");statement.close();// 事务提交connection.commit();} catch (SQLException e) {e.printStackTrace();try {connection.rollback();} catch (SQLException e1) {e1.printStackTrace();}}finally {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
事务隔离级别

事务隔离级别设置:
Spring的事务处理
基本概念

PlatformTransactionManager
#事务管理器,最核心接口
- getTransaction => 获取事务
- commit => 提交事务
- rollback => 回滚事务
TransactionDefinition
#事务定义,告诉spring开启一个什么特点,什么属性的事务
- 隔离级别:

- 默认超时
超时之后会销毁事务

- 事务传播行为
一般会设置为第一种PROPAGATION_REQUIRED

TransactionStatus
#正在运行的事务的状态
DataSourceTransactionManager
#基于数据源的事务管理器的实现类(一般用这个)
HibernateTransactionManager
#基于hibernate的事务管理器的实现类
JpaTransactionManager
#基于Jpa的事务管理器的实现类
Spring编程式事务处理
- 基于底层API的编程式事务管理
PlatformTransactionManager
TransactionDefinition
TransactionStatus
- 基于TransactionTemplate的编程式事务管理
TransactionTemplate
Spring声明式事务处理
Spring的声明式事务处理是建立在AOP的基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或加入一个事务,在执行完目标方法之后根据执行情况提交或回滚事务。
建议在开发中使用声明式事务,是因为这样可以使得业务代码纯粹干净,方便后期的代码维护。
- 基于TransactionInterceptor的声明式事务处理(不建议使用)
基于TransactionProxyFactoryBean的声明式事务处理(不建议使用)
基于
命名空间的声明式事务管理
resources/spring-service.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="spring-dao.xml"/>
<context:component-scan base-package="com.imooc.os.service.impl"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="find*" propagation="REQUIRED" read-only="true"/>
<tx:method name="search*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.imooc.os.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
</beans>
基于@Transactional的声明式事务管理
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <import resource="spring-dao.xml"/> <context:component-scan base-package="com.imooc.os.service.impl6"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>个人建议:
基于命名空间的声明式事务管理(这种方式最好) 业务代码最干净
- 虽然配置比@Transactional的方式复杂点,但是只需要配置一次就够了
基于@Transactional的声明式事务管理
- 虽然配置相对简单,但是需要在每个函数之前加上@Transactional注解,函数多的话就比较麻烦
