什么是事务
一组操作,要么都成功,要么都失败。
- 声明式事务:AOP
- 编程式事务:需要在代码中进行事务管理
使用Spring声明式事务
Mapper接口实现类
public interface IEmpMapper {
List<Emp> select();
int insert(Emp emp);
int delete(@Param("id")int id);
}
//继承SqlSessionDaoSupport
public class EmpMapper2 extends SqlSessionDaoSupport implements IEmpMapper{
//在调用select时,会先添加,在删除,最后查询
@Override
public List<Emp> select() {
insert(new Emp(1,"问问",56,"男","999@qq.com",new Dept(2)));
delete(2);
return getSqlSession().getMapper(IEmpMapper.class).select();
}
@Override
public int insert(Emp emp) {
return getSqlSession().getMapper(IEmpMapper.class).insert(emp);
}
@Override
public int delete(int id) {
return getSqlSession().getMapper(IEmpMapper.class).delete(id);
}
}
Mapper.xml映射文件
可以看到我故意写错了delete语句。如果执行上面的select()方法,添加成功过后,删除会失败。
这时候,数据库有被添加的数据,但是要删除的数据却还在。
应该用事务把select()方法看作是一个整体,全部成功就成功,一个失败了,全部回滚都失败。
<mapper namespace="com.lyd.mapper.IEmpMapper">
<select id="select" resultType="Emp">
select*from t_emp
</select>
<insert id="insert">
insert into t_emp values(null,#{empName},#{age},#{sex},#{email},#{dept.did})
</insert>
<delete id="delete">
deletes from t_emp where eid = #{id}
</delete>
</mapper>
在Spring配置文件里面配置事务
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--
DataSource:
使用Spring的数据源替换Mybatis的配置,c3p0 dbcp druid
这里使用Spring提供的JDBC
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--
sqlSessionFactory:
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--绑定Mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/lyd/mapper/*.xml"/>
</bean>
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!---->
<tx:attributes>
<tx:method name="query" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务的切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.lyd.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
<!--
上面都是固定的写法:
下面都是才是自己编写的实现类,有多少实现类就编写多少bean
注入sqlSession对象
-->
<bean id="empMapper2" class="com.lyd.mapper.EmpMapper2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
现在测试,哪怕insert()方法没问题,delete()方法失败了,最终insert()也没有真正的加入数据到数据库
@Test
public void test1() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
IEmpMapper iempMapper =context.getBean("empMapper2",IEmpMapper.class);
List<Emp> emps = iempMapper.select();
for (Emp emp: emps) {
System.out.println(emp.toString());
}
}