spring 事务怎么用 在什么情况下使用?

spring 事务怎么用 在什么情况下使用?,第1张

明确一下一般事务控制都是控制数据库数据提交的。
一般控制关联数据,例如插入一个部门的所有信息,包括人,部门信息,房间等信息
插入的时候都是有关联的,如果其中一个环节出现错误就会取消提交,否则或产生垃圾数据,这就是事务控制的主要作用。

我一般是这样理解的:spring只是控制数据库的事务提交和回滚,借助于java的反射机制,在事务控制的方法(通常是service层的方法)前后获取事务开启session,然后执行你的数据 *** 作,如果你的方法内有异常被抛出,spring会捕获异常并回滚你在这个方法内所有的数据 *** 作,如果成功则提交所有的数据,最后spring会帮你关闭需要关闭的东西。所以spring想要做的是,要程序员专注于写逻辑,不需要关系数据库何时开启和关闭连接。
打字很辛苦,给分吧

参考资料:


Spring
提供的事务管理可以分为两类:
编程式的和声明式的
。编程式的,比较灵活,但是代
码量大,存在重复的代码比较多;声明式的比编程式的更灵活方便。
1
、传统使用
JDBC
的事务管理
以往使用
JDBC
进行数据 *** 作,使用
DataSource
,从数据源中得到
Connection
,我们知
道数据源是线程安全的,
而连接不是线程安全的,
所以对每个请求都是从数据源中重新取出
一个连接。一般的数据源由容器进行管理,包括连接池。例如

TOMCAT

WEBSPHERE

WEBLOGIC
等这些
J2EE
商业容器都提供了这个功能。
以往的我们使用
JDBC
在写代码时,事务管理可能会是这样:
Connection conn = null;

try{
conn = DBConnectionFactorygetConnection;
connsetAutoCommit(false);
//do something
conncommit(); //commit transcation

}catch(Exception e){
connrollback();

}

finally{
try{
connclose();
} catch(SQLException se){ //do sth}
//close ResultSet,PreparedStatement,Connection
//notice:Maybe ocurr Exception when u close rs,pstmt,conn

}
按照以往的思路来写代码,代码量比较长,而且容易疏忽,忘掉一些
try/catch
,引发一
些异常无法
catch
,虽然有时候我们会写
DBTool
类,来关闭这些资源,并且保证在关闭这
些资源时,不向外抛异常,但是这样做会导致额外的麻烦。
2

Spring
提供的编程式的事务处理
Spring
提供了几个关于事务处理的类:
TransactionDefinition //
事务属性定义
TranscationStatus //
代表了当前的事务,可以提交,回滚。
PlatformTransactionManager
这个是
spring
提供的用于管理事务的基础接口,
其下有一个







AbstractPlatformTransactionManager



使










DataSourceTransactionManager
等都是这个类的子类。
我们使用编程式的事务管理流程可能如下:
(1)
声明数据源。
(2)













DataSourceTransactionManager,HibernateTransactionManger,JTA
TransactionManager

(3)
在我们的代码中加入事务处理代码:
TransactionDefinition td = new TransactionDefinition();

TransactionStatus ts = transactionManagergetTransaction(td);

try{
//do sth
transactionManagercommit(ts);

}catch(Exception e){transactionManagerrollback(ts);}
使用
Spring
提供的事务模板
TransactionTemplate

void add()

{
transactionTemplateexecute( new TransactionCallback(){
pulic Object doInTransaction(TransactionStatus ts)
{ //do sth}
}

}
TransactionTemplate
也是为我们省去了部分事务提交、回滚代码;定义事务模板时,需
注入事务管理对象。
3

Spring
声明式事务处理
Spring
声明式事务处理也主要使用了
IoC

AOP
思想,提供了
TransactionInterceptor

截器和常用的代理类
TransactionProxyFactoryBean
,可以直接对组件进行事务代理。
使用
TransactionInterceptor
的步骤:

1
)定义数据源,事务管理类

2
)定义事务拦截器
,
例如:

bean id = "transactionInterceptor"

class="orgspringframeworktransactioninterceptorTransactionInterceptor"


property name="transactionManager"
><
ref bean="transactionManager"/
><
/property


property name="transactionAttributeSource"


value

comtestUserManagerr=PROPAGATION_REQUIRED


/value


/property


/bean


3
)为组件声明一个代理类:
ProxyFactoryBean

bean id="userManager" class="orgspringframeworkaopframeworkProxyFactoryBean"


property name="proxyInterfaces"
><
value

comtestUserManager

/value
><
/property


property name="interceptorNames"


list


idref local="transactionInterceptor"/


/list


/property


/bean

使用
TransactionProxyFactoryBean


bean id="userManager"

class="orgspringframeworktransactioninterceptorTransactionProxyFactoryBean"


property name="transactionManager"
><
ref bean="transactionManager"/
><
/property


property name="target"
><
ref local="userManagerTarget"/
><
/property


property name="transactionAttributes"


props


prop key="insert"

PROPAGA
TION_REQUIRED

/prop


prop key="update"

PROPAGA
TION_REQUIRED

/prop


prop key=""

PROPAGATION_REQUIRED,readOnly

/prop


/props


/property


/bean

TransactionProxyFactoryBean
只是为组件的事务代理,如果我们要给组件添加一些业务
方面的验证等,
可以使用

TransactionTemplate
加拦截器方式,
为组件添加多个拦截器,
spring
AOP
中提供了三类
Advice,
即前增强,后增强,抛出异常时的增强,可以灵活使用。

不使用事务时,每次调用hibernateTemplate的方法会立刻进行事务提交
而使用事务后,会在你配置的类的方法执行完成后再进行事务提交,如果一个方法中同时进行了多次的插入、修改或删除 *** 作,会统一的进行提交或回滚,这样可以保证数据 *** 作会同时成功或失败,保证数据的完整性

在没有spring之前,事务的管理是相当复杂的,你要去考虑read or write,或者是autocommit或rollback,是相当费劲,而且错误频出的。
但有了spring之后,它可以将事务集中起来,用配置的方式(即声明式事务:即说它有事务就有了,说它没有事务,你在程序当中写了crud *** 作,也不会真正去执行)来统一管理事务,而且提供了相对完善的安全保证。
就说这么多了,只有你用了spring之后,才会明白真的好处。继续深入吧。

首先 @Transaction 是属于 Spring部分的
下面来说说使用
spring中的@Transaction配置详解
1、Spring默认Transactional事物管理机制
如果程序抛出的是运行期例外,则数据回滚 事物处理
如果是重新Exception例外,则数据不会滚。
可以通过配置修改该规则
@Transactional(noRollbackFor=RuntimeExceptionclass)方法事物说明
@Transactional(RollbackFor=Exceptionclas)
@Transactional(readyOnly=true)
@Transactional(timeout=100)默认30
@Transactional(isolation)数据库的隔离级别
{
Read Uncommited:读取未提交的数据(会出现脏读 不可重复读 幻读)
Read Commited:读已提交的数据(会出现不可重复读和幻读)
Repeatable Read:可重复读(会出现幻读)
Serializable:串行化
}
脏读:一个事务读取到另外一个事务未提交的更新的数据
不可重复读:在同一个事务中,多次读取同一个数据返回结果有所不同,就是后续的读取可以读到另外一个事务的已经提交的更新数据
可重复读:在同一个事务多次读取数据时,能够保证所读取的数据一样,也就是后读取的不能读到另外一个事务已经提交的数据
幻读: 一个事务读取到另外一个事务已经提交的更新的数据
针对查询方法
@Transactional(propagation=PropagationNOT_SUPPORTED)针对某个方法不开启事务
@Transactional(propagation=PropagationREQUIRED)spring默认的事务支持
Propagation参数解析
1、REQUIRED:业务方法需要在一个事务中运行。如果方法运行中,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。
2、NOT_SUPPORIED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。
3、REQUIRES_NEW:属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起, 新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。
4、MANDATORY:该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器会抛出例外。
5、SUPPORTS:这一事务属性表明,如果业务方法在某一个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
6、NEVER:指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。
7、NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按REQUIRED属性执行,它使用了一个单独事的事务, 这个事务拥有多个 可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只会对DataSourceTransactionManager事务管理器起效。

使用spring容器管理事务,要么用 aop 找到某一切面 去全局transactional 要么就是 注解模式 在指定的方法中进行事务控制。
spring会根据配置 对某方法中(属于切面或是被指定的方法)所有的DML动作 进行处理。

你spring事务理解不到位,再去看下相关资料吧。
你上边所说的inerst update 只要将dao放到一个service下去管理就行 。
spring在service中事务管理,是当他调用service中的一个方法的时候 就会开启一个事务,
直到你执行完这个方法,才会commit。所以只要其中有一个失败都会回滚


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13381926.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存