Spring对事务的支持
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring对事务的支持相关的知识,希望对你有一定的参考价值。
1、ThreadLocal
在写Spring对事务的支持之前要先了解一下ThreadLocal,当多个线程访问同一个成员变量时,如果这个变量不做处理,那肯定会造成线程不安全的问题啊。使用ThreadLocal就可以解决这个问题,ThreadLocal为每一个线程创建变量的一个副本,这样线程操作的其实是各自的副本,就不会产生线程不安全的问题。下面看个例子:
public class ThreadLocalTest { private ThreadLocal<Integer> num=new ThreadLocal<Integer>(){ @Override protected Integer initialValue() { return 0; } }; Integer getNextNum(){ num.set(num.get()+1); return num.get(); }; public static void main(String[] args){ ThreadLocalTest th=new ThreadLocalTest(); Test t1=new Test(th); Test t2=new Test(th); Test t3=new Test(th); t1.start(); t2.start(); t3.start(); } }
public class Test extends Thread{ private ThreadLocalTest th; public Test(ThreadLocalTest th) { this.th = th; } @Override public void run() { for (int i=0;i<3;i++){ System.out.println("thread["+Thread.currentThread().getName()+"] th["+th.getNextNum()+"]"); } }} //运行结果 thread[Thread-1] th[1] thread[Thread-0] th[1] thread[Thread-0] th[2] thread[Thread-0] th[3] thread[Thread-2] th[1] thread[Thread-2] th[2] thread[Thread-2] th[3] thread[Thread-1] th[2] thread[Thread-1] th[3]
运行结果显示了,虽然三个线程同时访问了一个对象,但是并没有互相影响,成员变量都是从初始值开始的。
ThreadLocal有四个方法:
1、protectd T initiaValue():给变量设置初始值
2、public T get():获取当前线程当前变量的值
3、public void set(T value):给当前线程的副本设值
4、public void remove() :删除当前线程的副本
2、Spring对事务管理的支持
spring提供了三个接口对事务进行管理,然后提供了实现类对不同的持久层框架进行支持。
三个接口分别是:
1、TransactionDefinition:定义了事务的属性。
a、事务传播行为
b、事务隔离级别
c、事务超时
d、是否是只读
源码如下:
public interface TransactionDefinition { int PROPAGATION_REQUIRED = 0; int PROPAGATION_SUPPORTS = 1; int PROPAGATION_MANDATORY = 2; int PROPAGATION_REQUIRES_NEW = 3; int PROPAGATION_NOT_SUPPORTED = 4; int PROPAGATION_NEVER = 5; int PROPAGATION_NESTED = 6; int ISOLATION_DEFAULT = -1; int ISOLATION_READ_UNCOMMITTED = 1; int ISOLATION_READ_COMMITTED = 2; int ISOLATION_REPEATABLE_READ = 4; int ISOLATION_SERIALIZABLE = 8; int TIMEOUT_DEFAULT = -1; int getPropagationBehavior(); int getIsolationLevel(); int getTimeout(); boolean isReadOnly(); String getName(); }
2、TransactionStatus:描述事务具体的运行状态,继承了SavepointManager接口
public interface TransactionStatus extends SavepointManager, Flushable { boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); void flush(); boolean isCompleted(); }
public interface SavepointManager { Object createSavepoint() throws TransactionException; void rollbackToSavepoint(Object var1) throws TransactionException; void releaseSavepoint(Object var1) throws TransactionException; }
boolean isNewTransaction():判断当前事务是否是一个新事务,如果返回false,说明当前事务已存在,或者该操作没在事务环境中。
boolean hasSavepoint():判断当前事务是否有保存点。
void setRollbackOnly():设置当前事务为rollback-only模式,事务管理器接收到这个指令之后会回滚事务
boolean isRollbackOnly():判断当前事务是否是rollback-only
void flush():用于刷新底层会话的修改到数据库
boolean isCompleted():判断当前事务是否已经结束
Object createSavepoint():创建保存点
void rollbackToSavepoint(Object var1) :使事务回滚到保存点上,回滚之后保存的自动释放
void releaseSavepoint(Object var1) :释放指定保存点
3、PlatFormTransactionManager: 事务管理器
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException; void commit(TransactionStatus var1) throws TransactionException; void rollback(TransactionStatus var1) throws TransactionException; }
TransactionStatus getTransaction(TransactionDefinition var1):事务管理器根据TransactionDefinition描述的事务属性创建一个事务,并返回一个 TransactionStatus用来具体描述事务的运行状态。
void commit(TransactionStatus var1):事务管理器根据事务的运行状态对事务进行提交操作,如果该事物被设置为rollback-only,则将事务回滚
void rollback(TransactionStatus var1): 事务管理器对事务进行回滚操作。
工作中使用Mybatis持久层框架,Mybatis事务管理器的实现类是
org.springframework.jdbc.datasource.DataSourceTransactionManager
需要在spring配置文件进行配置
3、使用XML配置声明式事务
Spring使用XML配置声明式事务分为两种,一种用TransactionProxyFactoryBean,一种用aop/tx,由于早期Spring没有aop的特性,所以用代理工厂的方式配置事务,现在这种方式已经很少使用,所以不研究了。下面研究下使用aop/tx,配置事务。
首先定义一个类。
@Service @Transactional public class BbtForum{ public ForumDao forumDao; public TopicDao topicDao; public PostDao postDao; public void addTopic(Topic topic){ topic.addTopic(topic); postDao.addPost(topic.getPost()); } public Forum getForum(int forumId){ return forumDao.getForum(forumId); } public void updateForum(Forum forum){ forumDao.updateForum(forum); } public int getForumNum(){ return forumDao.getForumNum(); } }
Spring通过<aop:pointcut>来指定需要织入增强的切点,此处定义的是该包下所有类的所有方法,通过<tx:advice>声明增强,此处需要事务管理器,通过<tx:method>为加入事务的方法指定属性,<tx:method>的属性有name,propagation,isolation,timeout,read-only,rollback-for,non-rollback-for
4、使用注解的方式配置事务
这也是我平时最常用的方式,使用注解配置事务需要先在配置文件中加载注解驱动
注解驱动配置后,就可以用@Transacational注解来配置事务,该注解有以下属性可以配置:propagation,isolation,read-only,timeout,rollbackFor,noRollbackFor,rollbackForClassName,noRollBackForClassName
@Transacational注解可以用在类上,代表该类所有的方法都运行在事务环境中,也可以单独配置在方法上,给方法设置特定的事务环境。但是一般不标注在接口或抽象类上,因为@Transacational不能被继承。
以上是关于Spring对事务的支持的主要内容,如果未能解决你的问题,请参考以下文章