以下是Springmvc中比较常用的,springboot中则省去了配置,直接使用注解打开即可。不过核心原理还是一样的。
使用步骤:
步骤一、在spring配置文件中引入<tx:>命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
步骤二、具有@Transactional 注解的bean自动配置为声明式事务支持
<!-- 事务管理器配置, Hibernate单数据源事务 --> <bean id="defaultTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />
步骤三、在接口或类的声明处 ,写一个@Transactional.要是只在接口上写, 接口的实现类就会继承下来、接口的实现类的具体方法,可以覆盖类声明处的设置 @Transactional //类级的注解、适用于类中所有的public的方法
事务的传播行为和隔离级别
在使用spring的注解式事务管理时,对事务的传播行为和隔离级别可能有点不知所措,下边就详细的介绍下以备方便查阅。
事物注解方式: @Transactional
当标于类前时, 标示类中所有方法都进行事物处理 , 例子:
@Transactional public class TestServiceBean implements TestService {}
当类中某些方法不需要事物时:
@Transactional public class TestServiceBean implements TestService { private TestDao dao; public void setDao(TestDao dao) { this.dao = dao; } @Transactional(propagation = Propagation.NOT_SUPPORTED) public List<Object> getAll() { return null; } }
事物传播行为介绍:
@Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下);
@Transactional(propagation=Propagation.NOT_SUPPORTED) 容器不为这个方法开启事务;
@Transactional(propagation=Propagation.REQUIRES_NEW) 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务;
@Transactional(propagation=Propagation.MANDATORY) 必须在一个已有的事务中执行,否则抛出异常;
@Transactional(propagation=Propagation.NEVER) 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反);
@Transactional(propagation=Propagation.SUPPORTS) 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务;
@Transactional(timeout=30)事物超时设置://默认是30秒 ;
:@Transactional(isolation = Isolation.READ_UNCOMMITTED)事务隔离级别,读取未提交数据(会出现脏读, 不可重复读) 基本不使用;
@Transactional(isolation = Isolation.READ_COMMITTED)读取已提交数据(会出现不可重复读和幻读);
@Transactional(isolation = Isolation.REPEATABLE_READ)可重复读(会出现幻读)@Transactional(isolation = Isolation.SERIALIZABLE)串行化;
MYSQL: 默认为REPEATABLE_READ级别SQLSERVER: 默认为READ_COMMITTED;
脏读 : 一个事务读取到另一事务未提交的更新数据。
不可重复读 : 在同一事务中, 多次读取同一数据返回的结果有所不同, 换句话说, 后续读取可以读到另一事务已提交的更新数据. 相反, "可重复读"在同一事务中多次读取数据时, 能够保证所读数据一样, 也就是后续读取不能读到另一事务已提交的更新数据。
幻读 : 一个事务读到另一个事务已提交的insert数据。