易网时代-编程资源站
Welcome
微信登录
首页
/
操作系统
/
Linux
/
Spring中事务管理浅谈
Spring中对事务的声明式管理
拿一个XML举例
[html]
<?xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<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"
xsi:schemaLocation
="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
事务管理目标Service
<bean
id
=
"fooService"
class
=
"x.y.service.DefaultFooService"
/>
切面配置,配置了切入点是执行FooService下的所有方法 和 切入点调用的通知器为txAdvice
<aop:config>
<aop:pointcut
id
=
"fooServiceOperation"
expression
=
"execution(* x.y.service.FooService.*(..))"
/>
<aop:advisor
advice-ref
=
"txAdvice"
pointcut-ref
=
"fooServiceOperation"
/>
</aop:config>
该通知器的具体配置,所使用的事务管理器,所配置的事务规则
<tx:advice
id
=
"txAdvice"
transaction-manager
=
"txManager"
>
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with "get" are read-only -->
<tx:method
name
=
"get*"
read-only
=
"true"
/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method
name
=
"*"
/>
</tx:attributes>
</tx:advice>
所选用的事务管理器,和作为启动参数塞入的dataSource
<bean
id
=
"txManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<property
name
=
"dataSource"
ref
=
"dataSource"
/>
</bean>
连接数据库的dataSource
<bean
id
=
"dataSource"
class
=
"org.apache.commons.dbcp.BasicDataSource"
destroy-method
=
"close"
>
<property
name
=
"driverClassName"
value
=
"Oracle.jdbc.driver.OracleDriver"
/>
<property
name
=
"url"
value
=
"jdbc:oracle:thin:@rj-t42:1521:elvis"
/>
<property
name
=
"username"
value
=
"scott"
/>
<property
name
=
"password"
value
=
"tiger"
/>
</bean>
</beans>
Spring中对事务管理的底层实现
以上的方法,选用了Spring本身自带的JDBC的事务控制器做处理。相关代码集中在
DataSourceTransactionManager中
比如,事务的取得并且将取得的事务捆绑进当前线程中
[java]
@Override
protected
Object doGetTransaction() {
DataSourceTransactionObject txObject =
new
DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(
this
.dataSource);
txObject.setConnectionHolder(conHolder,
false
);
return
txObject;
}
在比如事务的开始,
[java]
/**
* This implementation sets the isolation level but ignores the timeout.
*/
@Override
protected
void
doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con =
null
;
try
{
if
(txObject.getConnectionHolder() ==
null
||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon =
this
.dataSource.getConnection();
if
(logger.isDebugEnabled()) {
logger.debug(
"Acquired Connection ["
+ newCon +
"] for JDBC transaction"
);
}
txObject.setConnectionHolder(
new
ConnectionHolder(newCon),
true
);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(
true
);
con = txObject.getConnectionHolder().getConnection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don"t want to do it unnecessarily (for example if we"ve explicitly
// configured the connection pool to set it already).
if
(con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(
true
);
if
(logger.isDebugEnabled()) {
logger.debug(
"Switching JDBC Connection ["
+ con +
"] to manual commit"
);
}
con.setAutoCommit(
false
);
}
txObject.getConnectionHolder().setTransactionActive(
true
);
int
timeout = determineTimeout(definition);
if
(timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// Bind the session holder to the thread.
if
(txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
}
}
catch
(Exception ex) {
DataSourceUtils.releaseConnection(con,
this
.dataSource);
throw
new
CannotCreateTransactionException(
"Could not open JDBC Connection for transaction"
, ex);
}
}
等等这里就不多说了,起个头。
版权所有©石家庄振强科技有限公司2024
冀ICP备08103738号-5
网站地图