今天来记录一下在SSM项目中经常使用到的事务管理的配置,其实在spring中事务管理有很多方法,但今天我用的是最简单的这种(还不是因为懒~)aop自动管理事务。
1.首先我们需要有一个整合好的SSM框架项目,具体搭建步骤可以参考我的另一篇文章:最新版的SSM框架spring5.0搭建教程
2.下面就进入正题 了,我们只需要在spring-mybatis.xml文件中配置几个地方就可以了。
---->导入aop的引用:
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
---->配置spring的事务管理器(在我之前的配置文件中已经配置过了):
---->配置aop全局事务管理(我本机写的demo中业务不算复杂,也为了方便演示,所以直接切到controller层了,切入点可以根据自己的项目需要自行设置):
---->配置事务管理的通知(具体指定aop拦截到的哪些方法需要创建/使用事务):
配置到这里就完成了。
提别提醒:这几个bean的id可以自定义,但前提是能搞清楚他们用在哪里,不要改了名字又不知道怎么用了!
3.编写一个测试方法,我这边自己写了一个测试方法,模拟用户借书的操作。
一个人要去图书馆借书,那么我们需要记录两条记录,第一条是在借书人的信息表中记录这个人借阅的图书的book_id,第二条是在书库中记录这本书是被哪些user_id借走了。
两条记录都完整记录表示借阅成功,如果只登记了借书人借阅的书本信息,而没有登记图示的借阅人信息,就算借阅失败~
下面看一下实现代码:
---->controller层:
package com.ssm.controller;
import com.ssm.model.Book;
import com.ssm.model.User;
import com.ssm.service.BookServie;
import com.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by viking on 2018/07/15
* Library 接口类
*/
@RestController
@RequestMapping("library")
public class LibraryController {
@Autowired
private UserService userService;
@Autowired
private BookServie bookServie;
@RequestMapping("borrow")
public Object Borrow(String uname,String bname) throws Exception{
User user = userService.getUserByName(uname);
Book book = bookServie.getBookByName(bname);
if (user.getBid()==null) user.setBid(book.getId()+"");
else user.setBid(user.getBid()+";"+book.getId());
if (book.getUid()==null) book.setUid(user.getId()+"");
else book.setUid(book.getUid()+";"+user.getId());
userService.updateBid(user);
bookServie.updateUid(book);
return "借阅成功";
}
}
具体的service层和dao层代码就没必要展示了,重点逻辑都在这~ 如果有需要完整代码的评论联系。
4.下面我们测试一下:
正常操作之后两张表都记录了对应的数据。
再测试一下异常后的事务回滚:
在controller层方法中制造一个运行时异常:
然后测试运行效果:
DEBUG 2018-07-15 17:14:09,318 org.mybatis.spring.SqlSessionUtils: Creating a new SqlSession
DEBUG 2018-07-15 17:14:09,334 org.mybatis.spring.SqlSessionUtils: Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
DEBUG 2018-07-15 17:14:09,359 org.mybatis.spring.transaction.SpringManagedTransaction: JDBC Connection [jdbc:mysql://localhost:3306/mydatabase_test, UserName=root@localhost, MySQL Connector Java] will be managed by Spring
DEBUG 2018-07-15 17:14:09,369 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Preparing: SELECT * FROM USER WHERE name=?
DEBUG 2018-07-15 17:14:09,442 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 测试二(String)
DEBUG 2018-07-15 17:14:09,473 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1
DEBUG 2018-07-15 17:14:09,479 org.mybatis.spring.SqlSessionUtils: Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
DEBUG 2018-07-15 17:14:09,480 org.mybatis.spring.SqlSessionUtils: Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353] from current transaction
DEBUG 2018-07-15 17:14:09,482 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Preparing: SELECT * FROM BOOK WHERE book_name=?
DEBUG 2018-07-15 17:14:09,482 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 《时间移民》(String)
DEBUG 2018-07-15 17:14:09,484 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 1
DEBUG 2018-07-15 17:14:09,485 org.mybatis.spring.SqlSessionUtils: Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
DEBUG 2018-07-15 17:14:09,486 org.mybatis.spring.SqlSessionUtils: Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353] from current transaction
DEBUG 2018-07-15 17:14:09,487 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Preparing: UPDATE USER SET bid=? WHERE id=?
DEBUG 2018-07-15 17:14:09,499 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1;2(String), 2(Integer)
DEBUG 2018-07-15 17:14:09,530 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Updates: 1
DEBUG 2018-07-15 17:14:09,532 org.mybatis.spring.SqlSessionUtils: Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
-----------------制造一个运行时异常--------------
DEBUG 2018-07-15 17:14:09,534 org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization: Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
DEBUG 2018-07-15 17:14:09,535 org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization: Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3426d353]
控制台日志记录中执行了一条update语句后报了异常,程序终止运行,再看看数据库结果:
依然还是第一条记录,说明事务回滚了,测试通过~
通过上面几步简单的配置可以让我们很方便,很灵活的使用aop来管理我们的事务。
如果有不对的地方,欢迎各位大佬指教,如果有不懂的地方,也欢迎大家留言,我们一起讨论。