事务的四大特性:
(1)原子性:一个事务就是一个不可拆分的整体,要么全部执行要么全部不执行。(好比母鸡下蛋,要么这个蛋已经下下来了,要么没下下来,没有说这只蛋下了一半)
(2)一致性:数据不会因为事务的执行而遭到破坏。
(3)隔离性:一个事务的执行不会影响其他事务的执行,其他事务也不会影响该事物(就是并行执行的事务执行相互不干扰,各干各的)。
(4)持久性:事务一旦提交,那么他对数据库的改变是持久的。
事务的五大隔离级别:
(1)default:事务默认的隔离级别和具体的数据库有关,mysql为repeatable_read,oracle为read committed(oracle只支持两种事务 read_committed和serializable,所以oracle不支持脏读)。
(2)read_committed:读已提交,一个事务只能感知或操作一个已经提交的事务,可能会出现幻读和不可重复读的现象。
(3)read_uncommitted:读未提交,一个事务只能感知或操作一个没有提交的事务,可能会出现脏读,幻读和不可重复读的现象。
4:serializable:串行化,隔离级别最高,消耗资源最低但是代价最高,可以避免出现脏读,幻读和不可重复读。
事务的7大传播行为:
(1)Propagation.REQUIRED:如果调用方已经存在事务就加入到同一事务中去,如果没有事务就开启一个事务(常用哦)。
(2)Propagation.REQUIRES_NEW:不管调用方是否存在事务,自身都会开启一个新的事务。
(3)Propagation.SUPPORTS:调用方如果存在事务就加入到同一个事务中,如果不存在事务就以非事务的状态运行。
(4)Propagation.SUPPORTED:如果调用方已经存在事务,则该事务会被挂起,直到调用方运行完毕以后该事务就会恢复。
(5)Propagation.MANDATORY:如果调用方存在一个事务就加入到同一个事务中去,如果调用方不存在事务就抛出异常。
(6)Propagation.NEVER:如果调用方已经存在了事务,就会抛出异常。
(7)Propagation.NESTED:如果调用方存在一个事务就运行一个嵌套的事务,如果调用方不存在事务就开启一个新的事务(即以Propagation.REQUIRED的方式运行)
spring的事务管理
spring的事务管理有2种方式编程式事务管理和声明式事务管理
(1)编程式事务管理:编程式事务管理主要依赖于两大类PlafformTransactionManager和模板类TransactionTemplate.具体实现还请自行查找相关资料。因为编程式事务每次都要氮素实现,当业务量打功能需求较复杂时,使用编程式事务管理也是痛苦的,所以这里推荐老铁使用声明式事务吧。
(2)声明式事务管理:声明式事务属于无侵入式的,不会影响业务逻辑的实现。也是目前主流的事务管理方案。使用声明式事务的方式有两种基于注解和基于xml配置
--1:基于注解的声明式事务
在springmvc配置文件中添加开启使用事务的事务扫描驱动。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/DBNAME?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置事务注解扫描驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 指定数据源 -->
<beanid="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
然后在需要使用事务的方法或类上使用注解@Transactional事务扫描器会自动扫描带有该注解的方法或类并为他们开启一个事务
--2基于xml配置的声明式事务
<!-- 事务管理器 -->
<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="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.imooc.service.*.*(..))" />
</aop:config> 如上所示只需配置就可以了,比基于注解的事务管理要方便的多。其他地方就不用我们操心了,专心coding就OK