2018.5.28
一、spring事务管理接口
1、spring的TransactionManager接口:
在不同平台,操作事务的代码各不相同,因为spring提供了一个TransactionManager接口:
DataSourceTransactionManager 用于JDBC的事务管理
HibernateTransactionManager 用于hibernate的事务管理
jpaTransactionManager 用于Jpa的事务管理 ----------------------------Hibernate接口的实现----->Jpa是一个接口一个标准,参考hibernate

2、spring中TransactionManager接口的定义(源码)
package
com.lu.spring.service;
import
java.sql.Connection;
public
interface
TransactionDefinition
{
/**
* 绝大部分情况下只用前两个
*/
int
PROPAGATION_REQUIRED =
0
;
//支持当前事务,如果不存在,就新建一个。insert select 支持当前操作为查询操作 适应于增删改
int
PROPAGATION_SUPPORTS =
1
;
//支持当前事务,如果不存在,就不使用事务。 select select 查。
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
;
//默认级别,MySQL:默认为PRPEATABLE_READ级别 SQLSERVER:默认为READ_COMMITTED
int
ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
int
ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int
ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int
ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int
TIMEOUT_DEFAULT = -
1
;
//默认是-1,不超时,单位是秒
//事务的传播级别
int
getPropagationBehavior
();
//事务的隔离级别
int
getIsolationLevel
();
//事务超出时间
int
getTimeout
();
//是否只读
boolean
isReadOnly
();
String
getName
();
}
|
二、为转账案例添加事务
一、配置XML方式
1、转账事务的名称空间
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xmlns:context=
"http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans.xsd
http:
//www.springframework.org/schema/context
http:
//www.springframework.org/schema/context/spring-context.xsd
http:
//www.springframework.org/schema/aop
http:
//www.springframework.org/schema/aop/spring-aop.xsd
http:
//www.springframework.org/schema/tx
http:
//www.springframework.org/schema/tx/spring-tx.xsd
" >
|
3、配置事务管理器
<!-- 事务管理器 -->
<bean
name
=
"transactionManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<!-- 注入数据源 -->
<property
name
=
"dataSource"
ref
=
"dataSource"
></property>
</bean>
|
4、配置通知
查询为supports 且为只读事务read-only 增加效率
<!-- 通知 自己定义的不能用name 只能用ID-->
<tx:advice
id
=
"txAdvice"
transaction-manager
=
"transactionManager"
>
<tx:attributes>
<!-- 传播行为 -->
<!-- name:你要应用到哪个service方法中 -->
<!-- REQUIRED 支持当前事务,如果不存在,就新建一个 -->
<tx:method
name
=
"transfer"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"add*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"create*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"insert*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"save*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"update*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"modify*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"edit*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"delete*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"remove*"
propagation
=
"REQUIRED"
/>
<tx:method
name
=
"select*"
propagation
=
"SUPPORTS"
/>
<tx:method
name
=
"get*"
propagation
=
"SUPPORTS"
read-only=
"true"
/>
<tx:method
name
=
"find*"
propagation
=
"SUPPORTS"
read-only=
"true"
/>
<tx:method
name
=
"query*"
propagation
=
"SUPPORTS"
read-only=
"true"
/>
<tx:method
name
=
"search*"
propagation
=
"SUPPORTS"
read-only=
"true"
/>
</tx:attributes>
</tx:advice>
|
5、配置切面
<!-- 切面:通知织入切入点-->
<aop:config>
<!-- 切入点 -->
<aop:pointcut
expression
=
"execution(* com.lu.spring.service..*.*(..))"
id
=
"txPointcut"
/>
<aop:advisor
advice-ref
=
"txAdvice"
pointcut-ref
=
"txPointcut"
/>
</aop:config>
|
二、注解方式
不需要配置通知和切面但更多内容入侵代码当中
<!-- 事务管理器 -->
<bean
name
=
"transactionManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<!-- 注入数据源 -->
<property
name
=
"dataSource"
ref
=
"dataSource"
></property>
</bean>
<!-- 开启注解事务管理 -->
<tx:annotation-driven/>
|
但是需要在service层中事务上定义注解@Transactional,可以在类上全局注解事务管理,但是事务传播行为全是默认值
所以遇到特殊的增删改和查都要定义上各自的propagation(传播)。
@Service
(
"accountService"
)
@Transactional
public class AccountServiceImpl implements AccountService {
@Resource
(name=
"accountDao"
)
private AccountDao accountDao;
@Override
@Transactional
(propagation=Propagation.REQUIRED,readOnly=false,isolation=Isolation.REPEATABLE_READ)
public void transfer(Integer from, Integer to, Double money) {
accountDao
.subMoney(from, money);
//int a= 9/0;//无事务的用例 报异常之后只有from减钱,to不加钱。
accountDao
.addMoney(to, money);
}
}
|