Spring事务API介绍
JDBC编程中,事务如何管理?
JDBC 事务如何管理 编程式事务管理
Conneciton conn = getConnectioin();
conn.setAutoCommit(false);
try {
构成事务的多个操作的代码
//提交
conn.commit();
}catch(Exception e){
conn.rollback();
}
应用事务:
如果是单数据源的,应用数据库事务来实现应用事务是最简单的。
多数据源:JTA 分布式事务的一种处理方式
数据库事务 数据库使用过程多个操作要么都完成要么都不做的。
Spring中是如何进行事务管理的?
spring中 通过 AOP 来实现的事务管理
DataSourceTransactionManager 单数据源
多个dao的方法调用用的是同一个connection
conn.setAutoCommit(false);
用ThreadLocal来存储 ConnectionHolder
conn.commit();
conn.rollback();
spring 中应用事务有两种方式:
@Transaction
声明式事务管理
xml
切面类
tx:method 用来定义方法需要一个什么样的事务
传播行为,一定要背下来
隔离级别
TransactionInterceptor 事务aop的实现
TransactionAspectSupoort 具体的切面逻辑的实现
AbstractBeanDefinitionParser
tx:advice TxAdviceBeanDefinitionParser 会创建的bean是 TransactionInterceptor
Spring中做事务管理要面对各种各样的情况,它如何应对?
JDBC
,Mybatis
Hibernate
JPA
JMS
多数据源
如何做到业务代码中事务控制的代码一致?
面向接口编程,继承-多态
TransactionDefinition 事务定义
PlatformTransactionManager 事务管理器
TransactionStatus 事务的状态表示
Spring事务API使用的流程
Spring事务源码解读
以 DataSourceTransactionManager为例,来看它的过程
如何为多个Service方法应用事务管理?
AOP 你能自己写个切面吗?
来看看Spring中的事务AOP实现代
看看标签 tx:advice的解析
Spring事务属性解读
如何来定义一个事务
如何来定义一个事务
也请看看 @Transaction 标签 tx:advice的中 tx:method
这些属性将产生什么效果
请看看 TransactionInterceptor 的 invoke方法
请看看 DataSourceTransactionManager中的获取事务、关闭事务的源码
应用测试
切面
package com.dn.tx.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
//@Component
//@Aspect
public class TxAspect {
@Autowired
private PlatformTransactionManager txManager;
// @Around("@annotation(com.dn.andemo.annotation.NeedSetFieldValue)")\
@Around("execution (* com..service.*.*(..))")
public Object doInTransaction(ProceedingJoinPoint pjp) throws Throwable {
// 判断方法的名字是什么 add save delete update query get
TransactionDefinition td = new DefaultTransactionDefinition();
TransactionStatus ts = this.txManager.getTransaction(td);
Object ret = null;
try {
ret = pjp.proceed();
this.txManager.commit(ts);
} catch (Exception e) {
this.txManager.rollback(ts);
throw e;
}
return ret;
}
}
控制层
package com.dn.tx.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dn.tx.model.User;
import com.dn.tx.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/add")
public User add(User user) {
return this.userService.insertUser(user);
}
}
service层
package com.dn.tx.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.dn.tx.dao.LogDao;
import com.dn.tx.dao.UserDao;
import com.dn.tx.model.Log;
import com.dn.tx.model.User;
// 本类内方法指定使用缓存时,默认的名称就是userCache
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private LogDao logDao;
@Autowired
private PlatformTransactionManager txManager;
@Autowired
private LogService logService;
@Transactional
public User insertUser(User u) {
/*
* // 得到事务 TransactionDefinition definition = new
* DefaultTransactionDefinition(); TransactionStatus status =
* txManager.getTransaction(definition);
*
* try {
*/
// this.userDao.insert(u);
Log log = new Log(System.currentTimeMillis() + "",
System.currentTimeMillis() + "-" + u.getUserName());
this.doAddUser(u);
// this.logDao.insert(log);
this.logService.insertLog(log);
/*
* txManager.commit(status); } catch (Exception e) {
* txManager.rollback(status); throw e; }
*/
return this.userDao.find(u.getId());
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doAddUser(User u) {
this.userDao.insert(u);
}
public User updateUser(User u) {
this.userDao.update(u);
return this.userDao.find(u.getId());
}
public User findById(String id) {
System.err.println("根据id=" + id + "获取用户对象,从数据库中获取");
return this.userDao.find(id);
}
public void deleteById(String id) {
this.userDao.delete(id);
}
}
package com.dn.tx.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.dn.tx.dao.LogDao;
import com.dn.tx.model.Log;
// 本类内方法指定使用缓存时,默认的名称就是userCache
@Service
public class LogService {
@Autowired
private LogDao logDao;
@Autowired
private DataSourceTransactionManager txManager;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertLog(Log log) {
this.logDao.insert(log);
}
}
Dao
package com.dn.tx.dao;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.dn.tx.model.User;
@Mapper
public interface UserDao {
@Insert("insert t_user(id,user_name) values(#{id},#{userName})")
void insert(User u);
@Update("update t_user set user_name = #{userName} where id=#{id} ")
void update(User u);
@Delete("delete from t_user where id=#{id} ")
void delete(@Param("id") String id);
@Select("select id,user_name from t_user where id=#{id} ")
User find(@Param("id") String id);
}
package com.dn.tx.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import com.dn.tx.model.Log;
@Mapper
public interface LogDao {
@Insert("insert t_log(id,log) values(#{id},#{log})")
void insert(Log u);
}
实体类
package com.dn.tx.model;
import java.io.Serializable;
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5575893900970589345L;
private String id;
private String userName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
package com.dn.tx.model;
import java.io.Serializable;
public class Log implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5575893900970589345L;
private String id;
private String log;
public Log() {
}
public Log(String id, String log) {
super();
this.id = id;
this.log = log;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLog() {
return log;
}
public void setLog(String log) {
this.log = log;
}
}