一、事务
是指作为一个程序执行单元执行的一些列操作,要么完全执行,要么完全不执行。
二、事务的特性
1.原子性(atomicity)
一个事务是一个不可分割的工作单位。
2.一致性(consistency)
事务必须是使数据库从一个一致性状态变到另一个一致性状态。
3.隔离性(isolation)
一个事务的执行不能被其它事务干扰。
4.持久性(durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久的。
三、Mysql事务处理
1.基本规则
MySql中只有使用了Innodb数据库引擎的数据库或表才支持事务。
show engines; 查看服务器支持的引擎
default-storage-engine = Innodb my.ini修改默认引擎
MySql默认以自动提交(autocommit)模式运行。
2.语句
BEGIN(START TRANSACTION) 显示地开启一个事务
COMMIT 提交事务,并使已对数据库进行的所有修改变为永久性的
ROLLBACK 回滚事务,并撤销正在进行的所有未提交的修改
四、事务并发问题
1.脏读 (解决思路:只能读取持久层的数据,不能读取内存中的数据)
2.不可重复读 (解决思路:锁行) (修改)
3.幻读 (解决思路:锁表) (添加)
五、Mysql事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommited) | √ | √ | √ |
读已提交(read-commited) | × | √ | √ |
可重复读(repeated-read) | × | × | √ |
串行化(serializable) | × | × | × |
语句:
select @@tx_isolation --查询默认隔离级别
set session transaction isolation levex xxx --设置当前会话隔离级别
六、JDBC事务处理
1.Connection接口
JDBC事务处理是基于Connection的,JDBC通过Connection对象进行事务管理。
JDBC默认事务处理行为是自动提交。
2.事务相关方法
setAutoCommit 设置自动提交
commit 提交事务
rollback 回滚事务
七、JDBC事务隔离级别
1.隔离级别
TRANSACTION_NONE(不支持事务)
TRANSACTION_READ_UNCOMMOTTED
TRANSACTION_READ_COMMOTTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
2.事务隔离级别设置
getTransactionIsolation 获取当前隔离级别
setTransactionIsolation 设置隔离级别
八、Spring事务处理
1.TransactionDefinition接口
隔离级别
ISOLATION_DEFAULT(使用数据库默认即ISOLATION_REPEATABLE_READ)
ISOLATION_READ_UNCOMMOTTED
ISOLATION_READ_COMMOTTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
默认超时
TIMEOUT_DEFAULT 默认30秒
2.Spring事务传播行为
PROPAGATION_REQEIRED
支持当前事务,如果没有事务,就新建一个事务。
PROPAGATION_SUPPORTS
支持当前事务,如果没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就新建一个事务。
3.Spring编程式事务处理
基于底层API的编程式事务管理:
PlatformTransactionManager
TransactionDefinition
TransactionStatus
try{
//开启事务
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
//要执行的增删改方法
......
//提交事务
transactionManager.commit(transactionStatus);
}catch(Exception e){
transactionManager.rollback(transactionStatus);
}
基于TransactionTemplate的编程式事务管理
transactionTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus transactionStatus){
try{
//要执行的增删改方法
}catch(Exception e){
transactionStatus.setRollbackOnly();
}
return null;
}
})
//在匿名内部类里面调用外部的变量必须用final修饰该变量
4.Spring声明式事务处理
概述:Spring的声明式事务处理是建立在AOP基础之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
-
基于TransactionInterceptor的声明式事务处理
<!--配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--配置拦截目标类--> <bean id="userService" class="com.imooc.dao.UserService"/> <!--配置事务拦截器--> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <!--以get开头的方法,设置事务类型PROPAGATION_REQEIRED,只读--> <prop key="get*">PROPAGATION_REQEIRED,readonly</prop> <prop key="find*">PROPAGATION_REQEIRED,readonly</prop> </props> </property> </bean> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="userService"/> <property name="interceptorNames"> <list> <idref bean="transactionInterceptor"/> </list> </property> </bean>
-
基于TransactionProxyFactoryBean的声明式事务处理
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <!--以get开头的方法,设置事务类型PROPAGATION_REQEIRED,只读--> <prop key="get*">PROPAGATION_REQEIRED,readonly</prop> <prop key="find*">PROPAGATION_REQEIRED,readonly</prop> </props> </property> <property name="target" ref="userService"/> </bean>
-
基于命名空间的声明式事务管理 (常用)
<beans> <!--开启注解扫描--> <context:component-scan base-package="com.imooc.xxx"/> <!--配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--配置通知(增加的功能)--> <tx:advice id="txAdvice" reansaction-manager="transactionManager"> <!--目标方法--> <tx:attributes> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:point id="pointcut" expression="execution(* com.imooc.os.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/> </aop:config> </beans>
-
基于@Transactional的声明式事务管理 (常用)
<beans> <!--开启注解扫描--> <context:component-scan base-package="com.imooc.xxx"/> <!--配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
@Transactional(propagation=Propagation.REQUIRED)
public void addOrder(){
...
}