目录
事务是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作,这样可以防止出现脏数据,防止数据库数据出现问题。
JDBC: Connection con.commit(); con.rollback();
MyBatis: SqlSession sqlSession.commit(); sqlSession.rollback();
Hibernate: Session session.commit(); session.rollback();
事务管理器用来生成相应技术的连接+执行语句的对象。
如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
-
- <property name="dataSource" ref="dataSource">property>
- bean>

项目中的所有事务,必须添加到业务逻辑层上。
JDBC中是通过Connection对象进行事务管理,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。
Hibernate中是通过Transaction进行事务管理,处理方法与JDBC中类似。
Spring中也有自己的事务管理机制,一般是使用TransactionMananger(事务管理器)进行管理,可以通过Spring的注入来完成此功能。

多个事务之间的合并,互斥等都可以通过设置事务的传播特性来解决。
常用
PROPAGATION_REQUIRED:必被包含事务(增删改必用)
PROPAGATION_REQUIRES_NEW:自己新开事务,不管之前是否有事务
PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则支持事务,如果没有,不单开事务
PROPAGATION_NEVER:不能运行中事务中,如果包在事务中,抛异常
PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务的环境
不常用
PROPAGATION_MANDATORY:必须包在事务中,没有事务则抛异常
PROPAGATION_NESTED:嵌套事务

- @Service //交给Spring去创建对象
- @Transactional(propagation = Propagation.REQUIRED)
- public class UsersServiceImpl implements UsersService {
- @Autowired
- UsersMapper usersMapper;
-
- @Autowired
- AccountsService accountsService;
-
- @Override
- public int insert(Users users) {
- int num = usersMapper.insert(users);
- System.out.println("用户增加成功!num="+num);
-
- //调用帐户的增加操作,调用的帐户的业务逻辑层的功能
- num = accountsService.save(new Accounts(300,"王五","帐户好的呢!"));
- return num;
- }
- }

Spring非常有名的事务处理方式——声明式事务。
要求项目中的方法命名有规范
1)完成增加操作包含 add save insert set
2)更新操作包含 update change modify
3)删除操作包含 delete drop remove clear
4)查询操作包含 select find search get
配置事务切面时可以使用通配符 * 来匹配所有方法
-
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource">property>
- bean>
-
-
- <tx:advice id="myadvice" transaction-manager="transactionManager">
- <tx:attributes>
- <tx:method name="*select*" read-only="true"/>
- <tx:method name="*find*" read-only="true"/>
- <tx:method name="*search*" read-only="true"/>
- <tx:method name="*get*" read-only="true"/>
- <tx:method name="*insert*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
- <tx:method name="*add*" propagation="REQUIRED"/>
- <tx:method name="*save*" propagation="REQUIRED" no-rollback-for="ArithmeticException"/>
- <tx:method name="*set*" propagation="REQUIRED"/>
- <tx:method name="*update*" propagation="REQUIRED"/>
- <tx:method name="*change*" propagation="REQUIRED"/>
- <tx:method name="*modify*" propagation="REQUIRED"/>
- <tx:method name="*delete*" propagation="REQUIRED"/>
- <tx:method name="*remove*" propagation="REQUIRED"/>
- <tx:method name="*drop*" propagation="REQUIRED"/>
- <tx:method name="*clear*" propagation="REQUIRED"/>
- <tx:method name="*" propagation="SUPPORTS"/>
- tx:attributes>
- tx:advice>
-
- <aop:config>
- <aop:pointcut id="mycut" expression="execution(* com.bjpowernode.service.impl.*.*(..))">aop:pointcut>
- <aop:advisor advice-ref="myadvice" pointcut-ref="mycut">aop:advisor>
- aop:config>

1. 方法改名
2. 注解配置事务传播级别为开启新事务, @Transactional(read-only="false", propagation = Propagation.REQUIRES_NEW)
3. 在原有xml扫描方式中排除带有注解的方法或类
!(@annotation(org.springframework.transaction.annotation.Transactional) or @within(org.springframework.transaction.annotation.Transactional))
总结
1. 事务切面配置冲突时, 如果事务传播级别相同(默认REQUIRED), 以XML为准, 不区分加载顺序(order=x)
