一、事务
举个例子
脏读:当有一条①线程从数据库中select一条数据时,同时又又另一条②线程update同行数据,这就会导致我们①线程select出的数据和我们数据库中的数据不一致。从而出现问题。
事务回滚:当我们想让update和insert两条命令要么都成功,要么都不成功:原本我们数据库是默认执行一次默认修改命令就commit,这就导致当一条出现错误时,我们的另一条语句还是能正常的commit,从而出现问题。
我们的Spring就提供了一些操作,对这些事务进行处理。
二、Spring提供的事务操作
1、Spring提供了对事务的支持
Spring一共支持两种事务的操作:
1)编程式事务
自己手动控制,如关闭mysql的自动commit,设置回滚点,发生错误时rowback到指定的回滚点
2)声明式事务
Spring提供的annotation:@Transactional
我们下面只说的时声明式事务
2、Spring的声明式事务
使用方法:
再配置中添加
1)扫描包,哪些包下的哪些类可以使用@Transactional
<!--开启自动扫描-->//:spring自动扫描此包中及子包中的所有类 <context:component-scan base-package="">
2)配置数据源,我这里使用的是通过导dbcp2的包配置的dbcp2,使用的不是Spring自带的。
<bean class=".">
<property name="driverClassName" value=""/>
<property name="url" value="jdbc:mysql://localhost:3306/mynewdatabase"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
<property name="initialSize" value="2"/>
</bean>
3)配置事务,将上面的数据源当参数传入
<!--定义声明事务管理器-->
<bean class="">
<property name="dataSource" ref="dataSource"/>
</bean>
4)开启事务注解
<!--开启声明式事务-->
<tx:annotation-driven></tx:annotation-driven>
剩下的我们只要在扫描的那些类的的方法上加@Transactional即可。
@Transactional会处理我们方法中出现的runtimexception,发生runtimexception我们的@Transactional会让我们方法中的内容回滚。(对于不合理的情况,我们可以选择手动throw new exception)。
如果你在方法中使用了try/catch语句块对异常进行了处理,那么我们的@Transactional就无法接到异常
注意:当我们配置事务时id使用的不是transactionManage时,我们开启事务注解时会有一点点变化<tx:annotation-driven transactionManage="配置事务的id"></tx:annotation-driven>。
三、Spring事务的传播(重点)
事务的传播是只当两个事务方法组合到一起时,如何进行传播(一个事务方法中调用了另一个事务方法)
1、Spring提供的七种事务传播方式
种类:
1)REQUIRED(默认并常用)【required】
2)REQUIRES_NEW(常用)【requires_new】
3)SUPPORTS【supports】
4)NOT_SUPPORTED【not_supported】
5)MANDATORY【mandatory】
6)NEVER【never】
7)NESTED【nested】
2、使用方法
@Transactional(propagation = )
在我们注解中加参就行了,要使用哪种传播方式只需要更改propagation的值就行